/******************************************************************************
 * Copyright (c) 2000-2021 Ericsson Telecom AB
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
 *
 * Contributors:
 *   Baranyi, Botond
 *
 ******************************************************************************/

/******************************************************************************/
// TTCN-3 module JSON according to Annex A of ETSI ES 201 873-11 V4.8.1 (2018-05)
/******************************************************************************/

module JSON { 
 
//====================Types to define JSON Schemas ================================= 
 
  // JSON Number type (generic) 
  type float Number (!-infinity .. !infinity)  with { 
    variant "JSON:number" 
    }  
   
  // Integer type 
  type integer Integer (-infinity .. infinity)  with { 
    variant "JSON:integer" 
    }  
   
  // String type 
  type universal charstring String  with { 
    variant "JSON:string" 
    }  
   
   
  // Array type 
  type record of JSON.Values Array  with { 
    variant "JSON:array" 
    }  
   
  // Subsidiary array types 
  type record of JSON.String StrArray  with { 
    variant "JSON:array" 
    }  
 
  type record of JSON.Number NumArray  with { 
    variant "JSON:array" 
    }  
 
  type record of JSON.Integer IntArray  with { 
    variant "JSON:array" 
    }  
 
  type record of JSON.Bool BoolArray  with { 
    variant "JSON:array" 
    }  
 
  type record of JSON.Object ObjArray  with { 
    variant "JSON:array" 
    }  
   
  // Object member 
  type record ObjectMember {   
    JSON.String name, 
    JSON.Values value_ 
  }  with { 
    variant "JSON:objectMember" 
    }  
   
  // Generic JSON object type 
  type record Object { 
    record length (1..infinity) of JSON.ObjectMember memberList optional 
  }  with { 
    variant "JSON:object" 
    }  
   
   // note: The order of the alternatives in this type was changed.
   // More restrictive alternatives (such as 'int') were moved before less
   // restrictive ones (such as 'num') to ensure that a JSON value can be
   // decoded back into the same TTCN-3 value it was encoded from.
  type union Values { 
    JSON.String str,  
    JSON.Integer int, 
    JSON.Number num,
    JSON.Object object,   
    JSON.IntArray intArray,
    JSON.NumArray numArray,  
    JSON.StrArray strArray,
    JSON.BoolArray boolArray, 
    JSON.ObjArray objArray,  
    JSON.Array array,
    JSON.Bool bool, 
    JSON.Null null_ 
  }  with { 
    variant "asValue" 
    }  
 
  //JSON literals 
  //When only the true and false literals are allowed 
    type boolean Bool  with { variant "JSON:literal" }  
 
  //When only the null literal is allowed
  
    type enumerated Null { null_ } with { variant "JSON:literal" }  
 
 
//================================ Useful values ================================= 
 
   type JSON.String String_short with {variant "escape as short" };  
 
   type JSON.String String_usi with {variant "escape as usi" };  
 
   type JSON.String String_tr with {variant "escape as transparent" };  
 
   const JSON.String_short cs_bs := char(U8); // encoded as "\b" (Backspace)  
   const JSON.String_short cs_ht := char(U9); // encoded as "\t" (Horizontal tab)  
   const JSON.String_short cs_lf := char(UA); // encoded as "\n" (Line feed)  
   const JSON.String_short cs_ff := char(UC); // encoded as "\f" (Form feed)  
   const JSON.String_short cs_cr := char(UD); // encoded as "\r" (Carriage return)  
   const JSON.String_short cs_quot := """"; // encoded as "\"" (Quotation mark)
   
   const JSON.String_short cs_sol := "/"; // encoded as "\/" (Solidus or Slash)  
   const JSON.String_short cs_rs := "\\"; // encoded as "\\" (Reverse solidus or Backslash)  
 
   const JSON.String_usi cu_nul := char(U0); // encoded as "\u0000" (Null character)  
   const JSON.String_usi cu_soh := char(U1); // encoded as "\u0001", (Start of Heading   
   const JSON.String_usi cu_stx := char(U2); // encoded as "\u0002" (Start of Text)  
   const JSON.String_usi cu_etx := char(U3); // encoded as "\u0003" (End-of-text character)  
   const JSON.String_usi cu_eot := char(U4); // encoded as "\u0004" (End-of-transmission character)  
   const JSON.String_usi cu_enq := char(U5); // encoded as "\u0005" (Enquiry character)  
   const JSON.String_usi cu_ack := char(U6); // encoded as "\u0006" (Acknowledge character)  
   const JSON.String_usi cu_bel := char(U7); // encoded as "\u0007" (Bell character)  
   const JSON.String_usi cu_bs := char(U8); // encoded as "\u0008" (Backspace)  
   const JSON.String_usi cu_ht := char(U9); // encoded as "\u0009" (Horizontal tab)  
   const JSON.String_usi cu_lf := char(UA); // encoded as "\u000A" (Line feed)  
   const JSON.String_usi cu_vt := char(UB); // encoded as "\u000B" (Vertical tab)  
   const JSON.String_usi cu_ff := char(UC); // encoded as "\u000C" (Form feed)  
   const JSON.String_usi cu_cr := char(UD); // encoded as "\u000D" (Carriage return)  
   const JSON.String_usi cu_so := char(UE); // encoded as "\u000E" (Shift Out)  
   const JSON.String_usi cu_si := char(UF); // encoded as "\u000F" (Shift In)  
   const JSON.String_usi cu_dle := char(U10); // encoded as "\u0010" (Data Link Escape)  
   const JSON.String_usi cu_dc1 := char(U11); // encoded as "\u0011" (Device Control 1)  
   const JSON.String_usi cu_dc2 := char(U12); // encoded as "\u0012" (Device Control 2)  
   const JSON.String_usi cu_dc3 := char(U13); // encoded as "\u0013" (Device Control 3)  
   const JSON.String_usi cu_dc4 := char(U14); // encoded as "\u0014" (Device Control 4)  
   const JSON.String_usi cu_nak := char(U15); // encoded as "\u0015" (Negative-acknowledge charac.)  
   const JSON.String_usi cu_syn := char(U16); // encoded as "\u0016" (Synchronous Idle)  
   const JSON.String_usi cu_etb:= char(U17); // encoded as "\u0017" (End of Transmission Block)  
   const JSON.String_usi cu_can := char(U18); // encoded as "\u0018" (Cancel character)  
   const JSON.String_usi cu_em := char(U19); // encoded as "\u0019" (End of Medium)  
   const JSON.String_usi cu_sub := char(U1A); // encoded as "\u001A" (Substitute character)  
   const JSON.String_usi cu_esc := char(U1B); // encoded as "\u001B" (Escape character)  
   const JSON.String_usi cu_fs := char(U1C); // encoded as "\u001C" (File Separator)  
   const JSON.String_usi cu_gs := char(U1D); // encoded as "\u001D" (Group Separator)  
   const JSON.String_usi cu_rs := char(U1E); // encoded as "\u001E" (Record Separator)  
   const JSON.String_usi cu_us := char(U1F); // encoded as "\u001F" (Unit Separator)  
   const JSON.String_usi cu_sp := " "; // encoded as "\u0020" (Space)  
   const JSON.String_usi cu_quot := """"; // encoded as "\u0022" (Quotation mark)  
   const JSON.String_usi cu_sol := "/"; // encoded as "\u002F" (Solidus or Slash)  
   const JSON.String_usi cu_revs := "\\"; // encoded as "\u005C" (Reverse solidus or Backslash)  note: was originally "\", which is not legal in TITAN
   const JSON.String_usi cu_del := char(U7F); // encoded as "\u007F" (Delete)  
 
  //NOTE: see ISO/IEC 10646 [3] and https://en.wikipedia.org/wiki/List_of_Unicode_characters 
 
} with { encode "JSON" } //end module 
