================================================================================
api/protobuf
================================================================================

amends "../snippetTest.pkl"

import "pkl:protobuf"

local renderer = new protobuf.Renderer {}
local function renderValue(it: Any): String =
  renderer.renderValue(it)

/// For testing inheritance; [Foo] is the _base_ class.
local open class Foo {
  foo: String
}

/// For testing inheritance; [Bar] is the _derived_ class.
local class Bar extends Foo {
  foo = "Bar"
}

/// For testing the rendering of types inside a `VmTyped`.
local class Baz {
  foo: Foo
  bar: Bar
  foos: Listing<Foo>
  bars: Mapping<String, Bar>
}

/// For testing how rendering deals with _annotated_ (outer) collection types.
local class CollectionTypes {
  emptyList: List<Foo>
  list: List<Foo> = List(new Bar {}, new Foo { foo = "test foo" })
  emptyListing: Listing<Foo>
  listing: Listing<Foo> = new {
    new Bar { foo = "listing bar" }
    new Foo { foo = "listing foo" }
  }
  emptyMap: Map<Int, String>
  map: Map<Int, Foo> = Map(
    1, new Bar { foo = "first" },
    2, new Foo { foo = "second" }
  )
  emptyMapping: Mapping<Int, Bar>
  mapping: String =
    module.catch(() ->
      renderValue(new Mapping<Foo, Bar> {
        [new Foo { foo = "key foo" }] = new Bar { foo = "value bar" }
      })
    )
  emptySet: Set<Foo>
  set: Set<Foo> = Set(
    new Bar { foo = "setOne" },
    new Bar { foo = "setTwo" }
  )
  mappingWithUnannotatedValueType: Mapping<String, Listing> = new {
    ["some"] {
      new Bar {}
      new Bar {}
    }
  }
}

/// For testing _admissable_ mapping key types.
local class MappingKeys {
  string: Mapping<String, Bar>
  long: Mapping<Int, Bar>
  int: Mapping<Int32, Bar>
  short: Mapping<Int16, Bar>
  boolean: Mapping<Boolean, Bar>
}

/// For testing that using _inadmissable_ mapping key types does indeed throw.
local class InvalidMappingKey {
  foo: Mapping<Bar, Bar>
}

local typealias StringLiteralUnion
  = "Qux"
  | "quux"
  | "QUUX"

local typealias OpenEndedStringUnion
  = "corge"
  | String // Not a union of string literals, although fully String-y.

local typealias HeterogeneousUnion
  = "Grault"
  | "GRAULT"
  | Int
  | Foo

local typealias SynonymPureEnum = StringLiteralUnion

local class TypeAliasBehavior {
  doubleAlias: SynonymPureEnum
}

local class StringLiteralUnionBehavior {
  theProperty: StringLiteralUnion
}

local class OpenEndedStringUnionBehavior {
  theProperty: OpenEndedStringUnion
}

local class HeterogeneousUnionBehavior {
  theHeterogeneousUnion: Listing<HeterogeneousUnion>
}

local class HeterogeneousUnionBehaviorX {
  theHeterogeneousUnion: HeterogeneousUnion
}

local class InvalidUnionBehavior {
  myMapping: Mapping<HeterogeneousUnion, Int> = new {
    [5] = 5
  }
}

local class DynamicBehavior {
  myDynamic: Dynamic
}

local class DurationBehavior {
  myDuration: Duration = 42.ns
}

local class DataSizeBehavior {
  myDataSize: DataSize
}

local class SubtypingBehavior {
  myFoo: Foo
  myFooOrBar: (Foo|Bar)?
}

examples {
  ["Rendering primitive values"] {
    for (v in new Listing {
      true
      false

      -42 as Int8
      -42 as Int16
      -42 as Int32
      -42 as Int

      42 as UInt8
      42 as UInt16
      42 as UInt32
      42 as UInt

      -13.37 as Float

      -13.37 as Number
      13.37 as Number
      -42 as Number
      42 as Number

      "Hello world"

      10.min
      2.ms
      120.ns
      5.s + 120.ns
    }) {
      renderValue(v)
    }
  }

  ["Collection types"] {
    renderValue(new CollectionTypes {})
  }

  ["Typed objects rendered as protobuf.ProtoMessage"] {
    renderValue(new Foo { foo = "new" })
    renderValue(new Bar {})
    renderValue(new Bar { foo = "Baz" })
    renderValue(
      new Baz {
        foo {
          foo = "FOO"
        }
        foos {
          foo
          outer.bar
        }
        bars {
          ["default"] {}
          ["amended"] {
            foo = "Bars"
          }
        }
      }
    )
    renderValue(new DurationBehavior {})
  }

  ["Unsupported types"] {
    module.catch(() -> throw(renderValue(new DynamicBehavior {})))
    module.catch(() -> throw(renderValue(new DataSizeBehavior { myDataSize = 10.kb })))
  }

  ["Types not supported at top-level"] {
    module.catch(() -> throw(renderValue(Map(3,4))))
    module.catch(() -> throw(renderValue(new Mapping {[1] = 2})))
  }

  ["Keys in maps"] {
    renderValue(new MappingKeys {
      string {
        ["Hello world"] {}
      }
      long {
        [1337] {}
      }
      int {
        [42] {}
      }
      short {
        [1] {}
      }
      boolean {
        [false] {}
      }
    })
    module.catch(() -> throw(renderValue(new InvalidMappingKey {
      foo {
        [new Bar {}] {}
      }
    })))
  }

  ["typealiases"] {
    renderValue(new TypeAliasBehavior {})
  }

  ["unions"] {
    renderValue(new StringLiteralUnionBehavior {})
    renderValue(new OpenEndedStringUnionBehavior {})
    renderValue(new HeterogeneousUnionBehaviorX {
      theHeterogeneousUnion = "Grault"
    })
    renderValue(new HeterogeneousUnionBehavior {
      theHeterogeneousUnion {
        "Grault"
        0
        new Bar {}
      }
    })
    module.catch(() -> renderValue(new InvalidUnionBehavior {}))
  }
  ["subtypes"] {
    renderValue(new SubtypingBehavior {
      myFoo = new Foo { foo = "renders" }
    })
    module.catch(() -> 
      renderValue(new SubtypingBehavior {
        myFoo = new Bar { foo = "shouldn't render" }
      })
    )
    renderValue(new SubtypingBehavior {
      myFoo = new Foo { foo = "renders" }
      myFooOrBar = new Bar { foo = "also renders" }
    })
  }
}

--------------------------------------------------------------------------------

(module
  (moduleHeader
    (extendsOrAmendsClause
      (stringConstant)))
  (importClause
    (stringConstant))
  (classProperty
    (modifier)
    (identifier)
    (newExpr
      (type
        (qualifiedIdentifier
          (identifier)
          (identifier)))
      (objectBody)))
  (classMethod
    (methodHeader
      (modifier)
      (identifier)
      (parameterList
        (typedIdentifier
          (identifier)
          (typeAnnotation
            (type
              (qualifiedIdentifier
                (identifier))))))
      (typeAnnotation
        (type
          (qualifiedIdentifier
            (identifier)))))
    (methodCallExpr
      (variableExpr
        (identifier))
      (identifier)
      (argumentList
        (variableExpr
          (identifier)))))
  (lineComment)
  (clazz
    (modifier)
    (modifier)
    (identifier)
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier)))))))
  (lineComment)
  (clazz
    (modifier)
    (identifier)
    (classExtendsClause
      (qualifiedIdentifier
        (identifier)))
    (classBody
      (classProperty
        (identifier)
        (slStringLiteral))))
  (lineComment)
  (clazz
    (modifier)
    (identifier)
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier)))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier)))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier)))))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier)))
              (type
                (qualifiedIdentifier
                  (identifier)))))))))
  (lineComment)
  (clazz
    (modifier)
    (identifier)
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier)))))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier))))))
        (methodCallExpr
          (identifier)
          (argumentList
            (newExpr
              (type
                (qualifiedIdentifier
                  (identifier)))
              (objectBody))
            (newExpr
              (type
                (qualifiedIdentifier
                  (identifier)))
              (objectBody
                (objectProperty
                  (identifier)
                  (slStringLiteral)))))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier)))))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier))))))
        (newExpr
          (objectBody
            (objectElement
              (newExpr
                (type
                  (qualifiedIdentifier
                    (identifier)))
                (objectBody
                  (objectProperty
                    (identifier)
                    (slStringLiteral)))))
            (objectElement
              (newExpr
                (type
                  (qualifiedIdentifier
                    (identifier)))
                (objectBody
                  (objectProperty
                    (identifier)
                    (slStringLiteral))))))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier)))
              (type
                (qualifiedIdentifier
                  (identifier)))))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier)))
              (type
                (qualifiedIdentifier
                  (identifier))))))
        (methodCallExpr
          (identifier)
          (argumentList
            (intLiteral)
            (newExpr
              (type
                (qualifiedIdentifier
                  (identifier)))
              (objectBody
                (objectProperty
                  (identifier)
                  (slStringLiteral))))
            (intLiteral)
            (newExpr
              (type
                (qualifiedIdentifier
                  (identifier)))
              (objectBody
                (objectProperty
                  (identifier)
                  (slStringLiteral)))))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier)))
              (type
                (qualifiedIdentifier
                  (identifier)))))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))))
        (methodCallExpr
          (moduleExpr)
          (identifier)
          (argumentList
            (functionLiteral
              (parameterList)
              (methodCallExpr
                (identifier)
                (argumentList
                  (newExpr
                    (type
                      (qualifiedIdentifier
                        (identifier))
                      (typeArgumentList
                        (type
                          (qualifiedIdentifier
                            (identifier)))
                        (type
                          (qualifiedIdentifier
                            (identifier)))))
                    (objectBody
                      (objectEntry
                        (newExpr
                          (type
                            (qualifiedIdentifier
                              (identifier)))
                          (objectBody
                            (objectProperty
                              (identifier)
                              (slStringLiteral))))
                        (newExpr
                          (type
                            (qualifiedIdentifier
                              (identifier)))
                          (objectBody
                            (objectProperty
                              (identifier)
                              (slStringLiteral)))))))))))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier)))))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier))))))
        (methodCallExpr
          (identifier)
          (argumentList
            (newExpr
              (type
                (qualifiedIdentifier
                  (identifier)))
              (objectBody
                (objectProperty
                  (identifier)
                  (slStringLiteral))))
            (newExpr
              (type
                (qualifiedIdentifier
                  (identifier)))
              (objectBody
                (objectProperty
                  (identifier)
                  (slStringLiteral)))))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier)))
              (type
                (qualifiedIdentifier
                  (identifier))))))
        (newExpr
          (objectBody
            (objectEntry
              (slStringLiteral)
              (objectBody
                (objectElement
                  (newExpr
                    (type
                      (qualifiedIdentifier
                        (identifier)))
                    (objectBody)))
                (objectElement
                  (newExpr
                    (type
                      (qualifiedIdentifier
                        (identifier)))
                    (objectBody))))))))))
  (lineComment)
  (clazz
    (modifier)
    (identifier)
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier)))
              (type
                (qualifiedIdentifier
                  (identifier)))))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier)))
              (type
                (qualifiedIdentifier
                  (identifier)))))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier)))
              (type
                (qualifiedIdentifier
                  (identifier)))))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier)))
              (type
                (qualifiedIdentifier
                  (identifier)))))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier)))
              (type
                (qualifiedIdentifier
                  (identifier)))))))))
  (lineComment)
  (clazz
    (modifier)
    (identifier)
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier)))
              (type
                (qualifiedIdentifier
                  (identifier)))))))))
  (typeAlias
    (modifier)
    (identifier)
    (type
      (type
        (type
          (stringConstant))
        (type
          (stringConstant)))
      (type
        (stringConstant))))
  (typeAlias
    (modifier)
    (identifier)
    (type
      (type
        (stringConstant))
      (type
        (qualifiedIdentifier
          (identifier)))))
  (lineComment)
  (typeAlias
    (modifier)
    (identifier)
    (type
      (type
        (type
          (type
            (stringConstant))
          (type
            (stringConstant)))
        (type
          (qualifiedIdentifier
            (identifier))))
      (type
        (qualifiedIdentifier
          (identifier)))))
  (typeAlias
    (modifier)
    (identifier)
    (type
      (qualifiedIdentifier
        (identifier))))
  (clazz
    (modifier)
    (identifier)
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier)))))))
  (clazz
    (modifier)
    (identifier)
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier)))))))
  (clazz
    (modifier)
    (identifier)
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier)))))))
  (clazz
    (modifier)
    (identifier)
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier)))))))))
  (clazz
    (modifier)
    (identifier)
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier)))))))
  (clazz
    (modifier)
    (identifier)
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))
            (typeArgumentList
              (type
                (qualifiedIdentifier
                  (identifier)))
              (type
                (qualifiedIdentifier
                  (identifier))))))
        (newExpr
          (objectBody
            (objectEntry
              (intLiteral)
              (intLiteral)))))))
  (clazz
    (modifier)
    (identifier)
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier)))))))
  (clazz
    (modifier)
    (identifier)
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier))))
        (propertyCallExpr
          (intLiteral)
          (identifier)))))
  (clazz
    (modifier)
    (identifier)
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier)))))))
  (clazz
    (modifier)
    (identifier)
    (classBody
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (qualifiedIdentifier
              (identifier)))))
      (classProperty
        (identifier)
        (typeAnnotation
          (type
            (type
              (type
                (type
                  (qualifiedIdentifier
                    (identifier)))
                (type
                  (qualifiedIdentifier
                    (identifier))))))))))
  (classProperty
    (identifier)
    (objectBody
      (objectEntry
        (slStringLiteral)
        (objectBody
          (forGenerator
            (typedIdentifier
              (identifier))
            (newExpr
              (type
                (qualifiedIdentifier
                  (identifier)))
              (objectBody
                (objectElement
                  (trueLiteral))
                (objectElement
                  (asExpr
                    (binaryExpr
                      (asExpr
                        (binaryExpr
                          (asExpr
                            (binaryExpr
                              (asExpr
                                (binaryExpr
                                  (falseLiteral)
                                  (intLiteral))
                                (type
                                  (qualifiedIdentifier
                                    (identifier))))
                              (intLiteral))
                            (type
                              (qualifiedIdentifier
                                (identifier))))
                          (intLiteral))
                        (type
                          (qualifiedIdentifier
                            (identifier))))
                      (intLiteral))
                    (type
                      (qualifiedIdentifier
                        (identifier)))))
                (objectElement
                  (asExpr
                    (intLiteral)
                    (type
                      (qualifiedIdentifier
                        (identifier)))))
                (objectElement
                  (asExpr
                    (intLiteral)
                    (type
                      (qualifiedIdentifier
                        (identifier)))))
                (objectElement
                  (asExpr
                    (intLiteral)
                    (type
                      (qualifiedIdentifier
                        (identifier)))))
                (objectElement
                  (asExpr
                    (binaryExpr
                      (asExpr
                        (binaryExpr
                          (asExpr
                            (intLiteral)
                            (type
                              (qualifiedIdentifier
                                (identifier))))
                          (floatLiteral))
                        (type
                          (qualifiedIdentifier
                            (identifier))))
                      (floatLiteral))
                    (type
                      (qualifiedIdentifier
                        (identifier)))))
                (objectElement
                  (asExpr
                    (binaryExpr
                      (asExpr
                        (floatLiteral)
                        (type
                          (qualifiedIdentifier
                            (identifier))))
                      (intLiteral))
                    (type
                      (qualifiedIdentifier
                        (identifier)))))
                (objectElement
                  (asExpr
                    (intLiteral)
                    (type
                      (qualifiedIdentifier
                        (identifier)))))
                (objectElement
                  (slStringLiteral))
                (objectElement
                  (propertyCallExpr
                    (intLiteral)
                    (identifier)))
                (objectElement
                  (propertyCallExpr
                    (intLiteral)
                    (identifier)))
                (objectElement
                  (propertyCallExpr
                    (intLiteral)
                    (identifier)))
                (objectElement
                  (propertyCallExpr
                    (binaryExpr
                      (propertyCallExpr
                        (intLiteral)
                        (identifier))
                      (intLiteral))
                    (identifier)))))
            (objectBody
              (objectElement
                (methodCallExpr
                  (identifier)
                  (argumentList
                    (variableExpr
                      (identifier)))))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (identifier)
              (argumentList
                (newExpr
                  (type
                    (qualifiedIdentifier
                      (identifier)))
                  (objectBody)))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (identifier)
              (argumentList
                (newExpr
                  (type
                    (qualifiedIdentifier
                      (identifier)))
                  (objectBody
                    (objectProperty
                      (identifier)
                      (slStringLiteral)))))))
          (objectElement
            (methodCallExpr
              (identifier)
              (argumentList
                (newExpr
                  (type
                    (qualifiedIdentifier
                      (identifier)))
                  (objectBody)))))
          (objectElement
            (methodCallExpr
              (identifier)
              (argumentList
                (newExpr
                  (type
                    (qualifiedIdentifier
                      (identifier)))
                  (objectBody
                    (objectProperty
                      (identifier)
                      (slStringLiteral)))))))
          (objectElement
            (methodCallExpr
              (identifier)
              (argumentList
                (newExpr
                  (type
                    (qualifiedIdentifier
                      (identifier)))
                  (objectBody
                    (objectProperty
                      (identifier)
                      (objectBody
                        (objectProperty
                          (identifier)
                          (slStringLiteral))))
                    (objectProperty
                      (identifier)
                      (objectBody
                        (objectElement
                          (variableExpr
                            (identifier)))
                        (objectElement
                          (propertyCallExpr
                            (outerExpr)
                            (identifier)))))
                    (objectProperty
                      (identifier)
                      (objectBody
                        (objectEntry
                          (slStringLiteral)
                          (objectBody))
                        (objectEntry
                          (slStringLiteral)
                          (objectBody
                            (objectProperty
                              (identifier)
                              (slStringLiteral)))))))))))
          (objectElement
            (methodCallExpr
              (identifier)
              (argumentList
                (newExpr
                  (type
                    (qualifiedIdentifier
                      (identifier)))
                  (objectBody)))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (moduleExpr)
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList)
                  (throwExpr
                    (parenthesizedExpr
                      (methodCallExpr
                        (identifier)
                        (argumentList
                          (newExpr
                            (type
                              (qualifiedIdentifier
                                (identifier)))
                            (objectBody))))))))))
          (objectElement
            (methodCallExpr
              (moduleExpr)
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList)
                  (throwExpr
                    (parenthesizedExpr
                      (methodCallExpr
                        (identifier)
                        (argumentList
                          (newExpr
                            (type
                              (qualifiedIdentifier
                                (identifier)))
                            (objectBody
                              (objectProperty
                                (identifier)
                                (propertyCallExpr
                                  (intLiteral)
                                  (identifier)))))))))))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (moduleExpr)
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList)
                  (throwExpr
                    (parenthesizedExpr
                      (methodCallExpr
                        (identifier)
                        (argumentList
                          (methodCallExpr
                            (identifier)
                            (argumentList
                              (intLiteral)
                              (intLiteral)))))))))))
          (objectElement
            (methodCallExpr
              (moduleExpr)
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList)
                  (throwExpr
                    (parenthesizedExpr
                      (methodCallExpr
                        (identifier)
                        (argumentList
                          (newExpr
                            (type
                              (qualifiedIdentifier
                                (identifier)))
                            (objectBody
                              (objectEntry
                                (intLiteral)
                                (intLiteral))))))))))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (identifier)
              (argumentList
                (newExpr
                  (type
                    (qualifiedIdentifier
                      (identifier)))
                  (objectBody
                    (objectProperty
                      (identifier)
                      (objectBody
                        (objectEntry
                          (slStringLiteral)
                          (objectBody))))
                    (objectProperty
                      (identifier)
                      (objectBody
                        (objectEntry
                          (intLiteral)
                          (objectBody))))
                    (objectProperty
                      (identifier)
                      (objectBody
                        (objectEntry
                          (intLiteral)
                          (objectBody))))
                    (objectProperty
                      (identifier)
                      (objectBody
                        (objectEntry
                          (intLiteral)
                          (objectBody))))
                    (objectProperty
                      (identifier)
                      (objectBody
                        (objectEntry
                          (falseLiteral)
                          (objectBody)))))))))
          (objectElement
            (methodCallExpr
              (moduleExpr)
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList)
                  (throwExpr
                    (parenthesizedExpr
                      (methodCallExpr
                        (identifier)
                        (argumentList
                          (newExpr
                            (type
                              (qualifiedIdentifier
                                (identifier)))
                            (objectBody
                              (objectProperty
                                (identifier)
                                (objectBody
                                  (objectEntry
                                    (newExpr
                                      (type
                                        (qualifiedIdentifier
                                          (identifier)))
                                      (objectBody))
                                    (objectBody))))))))))))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (identifier)
              (argumentList
                (newExpr
                  (type
                    (qualifiedIdentifier
                      (identifier)))
                  (objectBody)))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (identifier)
              (argumentList
                (newExpr
                  (type
                    (qualifiedIdentifier
                      (identifier)))
                  (objectBody)))))
          (objectElement
            (methodCallExpr
              (identifier)
              (argumentList
                (newExpr
                  (type
                    (qualifiedIdentifier
                      (identifier)))
                  (objectBody)))))
          (objectElement
            (methodCallExpr
              (identifier)
              (argumentList
                (newExpr
                  (type
                    (qualifiedIdentifier
                      (identifier)))
                  (objectBody
                    (objectProperty
                      (identifier)
                      (slStringLiteral)))))))
          (objectElement
            (methodCallExpr
              (identifier)
              (argumentList
                (newExpr
                  (type
                    (qualifiedIdentifier
                      (identifier)))
                  (objectBody
                    (objectProperty
                      (identifier)
                      (objectBody
                        (objectElement
                          (slStringLiteral))
                        (objectElement
                          (intLiteral))
                        (objectElement
                          (newExpr
                            (type
                              (qualifiedIdentifier
                                (identifier)))
                            (objectBody))))))))))
          (objectElement
            (methodCallExpr
              (moduleExpr)
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList)
                  (methodCallExpr
                    (identifier)
                    (argumentList
                      (newExpr
                        (type
                          (qualifiedIdentifier
                            (identifier)))
                        (objectBody))))))))))
      (objectEntry
        (slStringLiteral)
        (objectBody
          (objectElement
            (methodCallExpr
              (identifier)
              (argumentList
                (newExpr
                  (type
                    (qualifiedIdentifier
                      (identifier)))
                  (objectBody
                    (objectProperty
                      (identifier)
                      (newExpr
                        (type
                          (qualifiedIdentifier
                            (identifier)))
                        (objectBody
                          (objectProperty
                            (identifier)
                            (slStringLiteral))))))))))
          (objectElement
            (methodCallExpr
              (moduleExpr)
              (identifier)
              (argumentList
                (functionLiteral
                  (parameterList)
                  (methodCallExpr
                    (identifier)
                    (argumentList
                      (newExpr
                        (type
                          (qualifiedIdentifier
                            (identifier)))
                        (objectBody
                          (objectProperty
                            (identifier)
                            (newExpr
                              (type
                                (qualifiedIdentifier
                                  (identifier)))
                              (objectBody
                                (objectProperty
                                  (identifier)
                                  (slStringLiteral)))))))))))))
          (objectElement
            (methodCallExpr
              (identifier)
              (argumentList
                (newExpr
                  (type
                    (qualifiedIdentifier
                      (identifier)))
                  (objectBody
                    (objectProperty
                      (identifier)
                      (newExpr
                        (type
                          (qualifiedIdentifier
                            (identifier)))
                        (objectBody
                          (objectProperty
                            (identifier)
                            (slStringLiteral)))))
                    (objectProperty
                      (identifier)
                      (newExpr
                        (type
                          (qualifiedIdentifier
                            (identifier)))
                        (objectBody
                          (objectProperty
                            (identifier)
                            (slStringLiteral)))))))))))))))
