1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
package Torello.Browser.JsonAST;

import Torello.Java.ReadOnly.ReadOnlyMap;
import Torello.Java.ReadOnly.ReadOnlySet;
import Torello.Java.ReadOnly.ReadOnlyTreeSet;

// These are a total of four "TypeNode's" inside of the 'browser_protocol.json' file that do not
// seem to obey the same rules that the other 1,000 types which are declared inside tha file 
// actually obey.
// 
// My Options are limited to:
// 
//  * Changing the entire AST Node structure to accomodate these four definitions
//  * Leaving the AST Node Structure alone, and handling these four seperate cases differently.
// 
// I'm going with the latter

class SPECIAL_CASES$TypeNode 
{
    // ---------------------------------------------------------------------------------------------
    // Special-Case: CDP "object" types with NO declared "properties" schema
    //
    // The Chrome DevTools Protocol guarantees that if a type has "type": "object", it normally
    // includes a non-empty "properties" array. There are exactly two exceptions across the entire
    // spec:
    //
    //   • Network.Headers        → represents an arbitrary dictionary of HTTP header name/value
    //                              pairs. Keys and values are not fixed in the protocol schema, so
    //                              the spec omits "properties" and leaves it as a free-form map.
    //
    //   • Tracing.MemoryDumpConfig → defined as an opaque JSON configuration blob
    //                               used when enabling "memory-infra" tracing. The
    //                               structure is intentionally unspecified and may
    //                               vary between Chromium builds.
    //
    // Both are effectively "generalized objects" whose internal shape is not known to the protocol
    // schema. They cannot be code-generated into a proper Java type with fields, so the safest
    // option is to expose them back to the caller as a raw JsonValue (caller is responsible for
    // interpreting the blob).
    //
    // This whitelist prevents false errors in our Modus Ponens/Tollens checks.
    // ---------------------------------------------------------------------------------------------
    // Above explanation provided by Chat-GPT, after some haggling & negotiation.
    // The more you argue with Chat-GPT the more value you get out of it...


    static final ReadOnlySet<String> OBJECT_WITHOUT_PROPERTIES_OK = new ReadOnlyTreeSet<>(
        String::compareTo,
        "Headers",           // Network.Headers: arbitrary header map
        "MemoryDumpConfig"   // Tracing.MemoryDumpConfig: opaque config blob
    );


    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    // SPECIAL CASES: TypeNode has "type": "array", and "items" : { "$ref":  "xxx"}
    // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    // 
    // These are OTHERWISE IMPOSSIBLE" Cases.
    // 
    // Case 1:
    // 
    // The "Browser API" ==> "DOMSnapshot Domain" ==> "StringIndex Type"
    // "StringIndex" is a renamed Integer-Type.  (It's just a "type": "integer")
    // 2nd "Type" definition, which IMMEDIATELY FOLLOWS "StringIndex" called "ArrayOfStrings".
    // It is an array of "StringIndex", making it an "int[]"
    // 
    // On Top of that!  There are two uses of "ArrayOfStrings", and both of them make the
    // **ONLY USE OF** Type "ArrayOfStrings" as an array itself! 
    // This means that the only real purpose of "ArrayOfStrings" is to engender a two dimensional 
    // String[][]-Array, and actually have it be of type "int[][]" (since the pointers are memory
    // addresses that exist inside of the browser, not inside of Java)
    // 
    // 
    // Case 2:
    // 
    // "Browser API" ==> "Target Domain" ==> "FilterEntry Type"
    // "FilterEntry" has two PPR / Fields declared, they are: exclude-boolean, type-string.
    // 2nd "Type" definition which IMMEDIATELY FOLLOWS "FilterEntry" called "TargetFilter"
    // It is an Array of "FilterEntry".
    //
    // I have absolutely no idea why "TargetFilter" needs to have its own dedicated Type-Name.
    // In other situations within these two JSON CDP-Specifications Files, whenever there needs to 
    // be an entire array of one of the CDP defined types, the PPR (field, parameter or return
    // value) ... the PPR just declares that is is an "array of", and then provides the name of the
    // CDP Class/Type that the PPR is an array of....
    // 
    // If that sounds like gobbledygook - well, that's what makes a JsonAST so unbelievablly 
    // difficult.  I mean, literally, this one single special case (that you are reading about 
    // right here, righ now) can make the whole development process stop for 6 months (as I go to
    // work on something else).  When the values of a String is - itself - "string" and the meaning
    // of a "type" is "array of 'type'", it becomes perfectly impossible to reason about any of 
    // this crapola that is going on...
    // 
    // In any case, within the entire 40K lines of JSON that compromise both the
    // files 'browser_protocl.json' and 'js_protocol.json', there are EXACTLY TWO (again, amongst 
    // thousands) ... exactly two "type" array types that are declared where the "type" Json 
    // Property of the "type" Json-Array is itself an "array" **AND** the "items" Json-Object,
    // itself, contains a "$ref" JSON Property **INSTEAD OF** of a "type" JSON Property.
    // 
    // These are those two "Array of $ref"

    static final ReadOnlyMap<String, String> ARRAY_OF_REF_TYPES = ReadOnlyMap.of
        ("ArrayOfStrings", "int[]", "TargetFilter", "FilterEntry[]");
}