------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                         R E P I N F O - I N P U T                        --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--          Copyright (C) 2018-2021, Free Software Foundation, Inc.         --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
-- for  more details.  You should have  received  a copy of the GNU General --
-- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
-- http://www.gnu.org/licenses for a complete copy of the license.          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Alloc;
with Csets;    use Csets;
with Hostparm; use Hostparm;
with Namet;    use Namet;
with Output;   use Output;
with Snames;   use Snames;
with Table;
with Ttypes;

package body Repinfo.Input is

   SSU : Pos renames Ttypes.System_Storage_Unit;
   --  Value for Storage_Unit

   type JSON_Entity_Kind is (JE_Record_Type, JE_Array_Type, JE_Other);
   --  Kind of an entity

   type JSON_Entity_Node (Kind : JSON_Entity_Kind := JE_Other) is record
      Esize   : Node_Ref_Or_Val;
      RM_Size : Node_Ref_Or_Val;
      case Kind is
         when JE_Record_Type => Variant        : Nat;
         when JE_Array_Type  => Component_Size : Node_Ref_Or_Val;
         when JE_Other       => Dummy          : Boolean;
      end case;
   end record;
   pragma Unchecked_Union (JSON_Entity_Node);
   --  Record to represent an entity

   package JSON_Entity_Table is new Table.Table (
      Table_Component_Type => JSON_Entity_Node,
      Table_Index_Type     => Nat,
      Table_Low_Bound      => 1,
      Table_Initial        => Alloc.Rep_JSON_Table_Initial,
      Table_Increment      => Alloc.Rep_JSON_Table_Increment,
      Table_Name           => "JSON_Entity_Table");
   --  Table of entities

   type JSON_Component_Node is record
      Bit_Offset : Node_Ref_Or_Val;
      Esize      : Node_Ref_Or_Val;
   end record;
   --  Record to represent a component

   package JSON_Component_Table is new Table.Table (
      Table_Component_Type => JSON_Component_Node,
      Table_Index_Type     => Nat,
      Table_Low_Bound      => 1,
      Table_Initial        => Alloc.Rep_JSON_Table_Initial,
      Table_Increment      => Alloc.Rep_JSON_Table_Increment,
      Table_Name           => "JSON_Component_Table");
   --  Table of components

   type JSON_Variant_Node is record
      Present : Node_Ref_Or_Val;
      Variant : Nat;
      Next    : Nat;
   end record;
   --  Record to represent a variant

   package JSON_Variant_Table is new Table.Table (
      Table_Component_Type => JSON_Variant_Node,
      Table_Index_Type     => Nat,
      Table_Low_Bound      => 1,
      Table_Initial        => Alloc.Rep_JSON_Table_Initial,
      Table_Increment      => Alloc.Rep_JSON_Table_Increment,
      Table_Name           => "JSON_Variant_Table");
   --  Table of variants

   -------------------------------------
   --  Get_JSON_Component_Bit_Offset  --
   -------------------------------------

   function Get_JSON_Component_Bit_Offset
     (Name        : String;
      Record_Name : String) return Node_Ref_Or_Val
   is
      Namid : constant Valid_Name_Id := Name_Find (Record_Name & '.' & Name);
      Index : constant Int := Get_Name_Table_Int (Namid);

   begin
      --  Return No_Uint if no information is available for the component

      if Index = 0 then
         return No_Uint;
      end if;

      return JSON_Component_Table.Table (Index).Bit_Offset;
   end Get_JSON_Component_Bit_Offset;

   -------------------------------
   --  Get_JSON_Component_Size  --
   -------------------------------

   function Get_JSON_Component_Size (Name : String) return Node_Ref_Or_Val is
      Namid : constant Valid_Name_Id := Name_Find (Name);
      Index : constant Int := Get_Name_Table_Int (Namid);

   begin
      --  Return No_Uint if no information is available for the component

      if Index = 0 then
         return No_Uint;
      end if;

      return JSON_Entity_Table.Table (Index).Component_Size;
   end Get_JSON_Component_Size;

   ----------------------
   --  Get_JSON_Esize  --
   ----------------------

   function Get_JSON_Esize (Name : String) return Node_Ref_Or_Val is
      Namid : constant Valid_Name_Id := Name_Find (Name);
      Index : constant Int := Get_Name_Table_Int (Namid);

   begin
      --  Return No_Uint if no information is available for the entity

      if Index = 0 then
         return No_Uint;
      end if;

      return JSON_Entity_Table.Table (Index).Esize;
   end Get_JSON_Esize;

   ----------------------
   --  Get_JSON_Esize  --
   ----------------------

   function Get_JSON_Esize
     (Name        : String;
      Record_Name : String) return Node_Ref_Or_Val
   is
      Namid : constant Valid_Name_Id := Name_Find (Record_Name & '.' & Name);
      Index : constant Int := Get_Name_Table_Int (Namid);

   begin
      --  Return No_Uint if no information is available for the entity

      if Index = 0 then
         return No_Uint;
      end if;

      return JSON_Component_Table.Table (Index).Esize;
   end Get_JSON_Esize;

   ------------------------
   --  Get_JSON_RM_Size  --
   ------------------------

   function Get_JSON_RM_Size (Name : String) return Node_Ref_Or_Val is
      Namid : constant Valid_Name_Id := Name_Find (Name);
      Index : constant Int := Get_Name_Table_Int (Namid);

   begin
      --  Return No_Uint if no information is available for the entity

      if Index = 0 then
         return No_Uint;
      end if;

      return JSON_Entity_Table.Table (Index).RM_Size;
   end Get_JSON_RM_Size;

   -----------------------
   --  Read_JSON_Stream --
   -----------------------

   procedure Read_JSON_Stream (Text : Text_Buffer; File_Name : String) is

      type Text_Position is record
         Index  : Text_Ptr := 0;
         Line   : Natural := 0;
         Column : Natural := 0;
      end record;
      --  Record to represent position in the text

      type Token_Kind is
        (J_NULL,
         J_TRUE,
         J_FALSE,
         J_NUMBER,
         J_INTEGER,
         J_STRING,
         J_ARRAY,
         J_OBJECT,
         J_ARRAY_END,
         J_OBJECT_END,
         J_COMMA,
         J_COLON,
         J_EOF);
      --  JSON token kind. Note that in ECMA 404 there is no notion of integer.
      --  Only numbers are supported. In our implementation we return J_INTEGER
      --  if there is no decimal part in the number. The semantic is that this
      --  is a J_NUMBER token that might be represented as an integer. Special
      --  token J_EOF means that end of stream has been reached.

      function Decode_Integer (Lo, Hi : Text_Ptr) return Uint;
      --  Decode and return the integer in Text (Lo .. Hi)

      function Decode_Name (Lo, Hi : Text_Ptr) return Valid_Name_Id;
      --  Decode and return the name in Text (Lo .. Hi)

      function Decode_Symbol (Lo, Hi : Text_Ptr) return TCode;
      --  Decode and return the expression symbol in Text (Lo .. Hi)

      procedure Error (Msg : String);
      pragma No_Return (Error);
      --  Print an error message and raise an exception

      procedure Read_Entity;
      --  Read an entity

      function Read_Name return Valid_Name_Id;
      --  Read a name

      function Read_Name_With_Prefix return Valid_Name_Id;
      --  Read a name and prepend a prefix

      function Read_Number return Uint;
      --  Read a number

      function Read_Numerical_Expr return Node_Ref_Or_Val;
      --  Read a numerical expression

      procedure Read_Record;
      --  Read a record

      function Read_String return Valid_Name_Id;
      --  Read a string

      procedure Read_Token
        (Kind        : out Token_Kind;
         Token_Start : out Text_Position;
         Token_End   : out Text_Position);
      --  Read a token and return it (this is a standard JSON lexer)

      procedure Read_Token_And_Error
        (TK          : Token_Kind;
         Token_Start : out Text_Position;
         Token_End   : out Text_Position);
      pragma Inline (Read_Token_And_Error);
      --  Read a specified token and error out on failure

      function Read_Variant_Part return Nat;
      --  Read a variant part

      procedure Skip_Value;
      --  Skip a value

      Pos : Text_Position := (Text'First, 1, 1);
      --  The current position in the text buffer

      Name_Buffer : Bounded_String (4 * Max_Name_Length);
      --  The buffer used to build full qualifed names

      Prefix_Len : Natural := 0;
      --  The length of the prefix present in Name_Buffer

      ----------------------
      --  Decode_Integer  --
      ----------------------

      function Decode_Integer (Lo, Hi : Text_Ptr) return Uint is
         Len  : constant Nat := Int (Hi) - Int (Lo) + 1;

      begin
         --  Decode up to 9 characters manually, otherwise call into Uint

         if Len < 10 then
            declare
               Val : Int := 0;

            begin
               for J in Lo .. Hi loop
                  Val := Val * 10
                           + Character'Pos (Text (J)) - Character'Pos ('0');
               end loop;
               return UI_From_Int (Val);
            end;

         else
            declare
               Val : Uint := Uint_0;

            begin
               for J in Lo .. Hi loop
                  Val := Val * 10
                           + Character'Pos (Text (J)) - Character'Pos ('0');
               end loop;
               return Val;
            end;
         end if;
      end Decode_Integer;

      -------------------
      --  Decode_Name  --
      -------------------

      function Decode_Name (Lo, Hi : Text_Ptr) return Valid_Name_Id is
      begin
         --  Names are stored in lower case so fold them if need be

         if Is_Upper_Case_Letter (Text (Lo)) then
            declare
               S : String (Integer (Lo) .. Integer (Hi));

            begin
               for J in Lo .. Hi loop
                  S (Integer (J)) := Fold_Lower (Text (J));
               end loop;

               return Name_Find (S);
            end;

         else
            declare
               S : String (Integer (Lo) .. Integer (Hi));
               for S'Address use Text (Lo)'Address;

            begin
               return Name_Find (S);
            end;
         end if;
      end Decode_Name;

      ---------------------
      --  Decode_Symbol  --
      ---------------------

      function Decode_Symbol (Lo, Hi : Text_Ptr) return TCode is

         function Cmp12 (A, B : Character) return Boolean;
         pragma Inline (Cmp12);
         --  Compare Text (Lo + 1 .. Lo + 2) with A & B.

         -------------
         --  Cmp12  --
         -------------

         function Cmp12 (A, B : Character) return Boolean is
         begin
            return Text (Lo + 1) = A and then Text (Lo + 2) = B;
         end Cmp12;

         Len : constant Nat := Int (Hi) - Int (Lo) + 1;

      --  Start of processing for Decode_Symbol

      begin
         case Len is
            when 1 =>
               case Text (Lo) is
                  when '+' =>
                     return Plus_Expr;
                  when '-' =>
                     return Minus_Expr; -- or Negate_Expr
                  when '*' =>
                     return Mult_Expr;
                  when '<' =>
                     return Lt_Expr;
                  when '>' =>
                     return Gt_Expr;
                  when '&' =>
                     return Bit_And_Expr;
                  when '#' =>
                     return Discrim_Val;
                  when others =>
                     null;
               end case;
            when 2 =>
               if Text (Lo) = '/' then
                  case Text (Lo + 1) is
                     when 't' =>
                        return Trunc_Div_Expr;
                     when 'c' =>
                        return Ceil_Div_Expr;
                     when 'f' =>
                        return Floor_Div_Expr;
                     when 'e' =>
                        return Exact_Div_Expr;
                     when others =>
                        null;
                  end case;
               elsif Text (Lo + 1) = '=' then
                  case Text (Lo) is
                     when '<' =>
                        return Le_Expr;
                     when '>' =>
                        return Ge_Expr;
                     when '=' =>
                        return Eq_Expr;
                     when '!' =>
                        return Ne_Expr;
                     when others =>
                        null;
                  end case;
               elsif Text (Lo) = 'o' and then Text (Lo + 1) = 'r' then
                  return Truth_Or_Expr;
               end if;
            when 3 =>
               case Text (Lo) is
                  when '?' =>
                     if Cmp12 ('<', '>') then
                        return Cond_Expr;
                     end if;
                  when 'a' =>
                     if Cmp12 ('b', 's') then
                        return Abs_Expr;
                     elsif Cmp12 ('n', 'd') then
                        return Truth_And_Expr;
                     end if;
                  when 'm' =>
                     if Cmp12 ('a', 'x') then
                        return Max_Expr;
                     elsif Cmp12 ('i', 'n') then
                        return Min_Expr;
                     end if;
                  when 'n' =>
                     if Cmp12 ('o', 't') then
                        return Truth_Not_Expr;
                     end if;
                  when 'x' =>
                     if Cmp12 ('o', 'r') then
                        return Truth_Xor_Expr;
                     end if;
                  when 'v' =>
                     if Cmp12 ('a', 'r') then
                        return Dynamic_Val;
                     end if;
                  when others =>
                     null;
               end case;
            when 4 =>
               if Text (Lo) = 'm'
                 and then Text (Lo + 1) = 'o'
                 and then Text (Lo + 2) = 'd'
               then
                  case Text (Lo + 3) is
                     when 't' =>
                        return Trunc_Mod_Expr;
                     when 'c' =>
                        return Ceil_Mod_Expr;
                     when 'f' =>
                        return Floor_Mod_Expr;
                     when others =>
                        null;
                  end case;
               end if;

               pragma Annotate
                 (CodePeer, Intentional,
                  "condition predetermined", "Error called as defensive code");

            when others =>
               null;
         end case;

         Error ("unknown symbol");
      end Decode_Symbol;

      -----------
      -- Error --
      -----------

      procedure Error (Msg : String) is
         L : constant String := Pos.Line'Img;
         C : constant String := Pos.Column'Img;

      begin
         Set_Standard_Error;
         Write_Eol;
         Write_Str (File_Name);
         Write_Char (':');
         Write_Str (L (L'First + 1 .. L'Last));
         Write_Char (':');
         Write_Str (C (C'First + 1 .. C'Last));
         Write_Char (':');
         Write_Line (Msg);
         raise Invalid_JSON_Stream;
      end Error;

      ------------------
      --  Read_Entity --
      ------------------

      procedure Read_Entity is
         Ent         : JSON_Entity_Node;
         Nam         : Name_Id := No_Name;
         Siz         : Node_Ref_Or_Val;
         Token_Start : Text_Position;
         Token_End   : Text_Position;
         TK          : Token_Kind;

      begin
         Ent.Esize          := No_Uint;
         Ent.RM_Size        := No_Uint;
         Ent.Component_Size := No_Uint;

         --  Read the members as string : value pairs

         loop
            case Read_String is
               when Name_Name =>
                  Nam := Read_Name;
               when Name_Record =>
                  if Nam = No_Name then
                     Error ("name expected");
                  end if;
                  Ent.Variant := 0;
                  Prefix_Len := Natural (Length_Of_Name (Nam));
                  Name_Buffer.Chars (1 .. Prefix_Len) := Get_Name_String (Nam);
                  Read_Record;
               when Name_Variant =>
                  Ent.Variant := Read_Variant_Part;
               when Name_Size =>
                  Siz := Read_Numerical_Expr;
                  Ent.Esize := Siz;
                  Ent.RM_Size := Siz;
               when Name_Object_Size =>
                  Ent.Esize := Read_Numerical_Expr;
               when Name_Value_Size =>
                  Ent.RM_Size := Read_Numerical_Expr;
               when Name_Component_Size =>
                  Ent.Component_Size := Read_Numerical_Expr;
               when others =>
                  Skip_Value;
            end case;

            Read_Token (TK, Token_Start, Token_End);
            if TK = J_OBJECT_END then
               exit;
            elsif TK /= J_COMMA then
               Error ("comma expected");
            end if;
         end loop;

         --  Store the entity into the table

         JSON_Entity_Table.Append (Ent);

         --  Associate the name with the entity

         if Nam = No_Name then
            Error ("name expected");
         end if;

         Set_Name_Table_Int (Nam, JSON_Entity_Table.Last);
      end Read_Entity;

      -----------------
      --  Read_Name  --
      -----------------

      function Read_Name return Valid_Name_Id is
         Token_Start : Text_Position;
         Token_End   : Text_Position;

      begin
         --  Read a single string

         Read_Token_And_Error (J_STRING, Token_Start, Token_End);

         return Decode_Name (Token_Start.Index + 1, Token_End.Index - 1);
      end Read_Name;

      -----------------------------
      --  Read_Name_With_Prefix  --
      -----------------------------

      function Read_Name_With_Prefix return Valid_Name_Id is
         Len         : Natural;
         Lo, Hi      : Text_Ptr;
         Token_Start : Text_Position;
         Token_End   : Text_Position;

      begin
         --  Read a single string

         Read_Token_And_Error (J_STRING, Token_Start, Token_End);
         Lo := Token_Start.Index + 1;
         Hi := Token_End.Index - 1;

         --  Prepare for the concatenation with the prefix

         Len := Integer (Hi) - Integer (Lo) + 1;
         if Prefix_Len + 1 + Len > Name_Buffer.Max_Length then
            Error ("Name buffer too small");
         end if;

         Name_Buffer.Length := Prefix_Len + 1 + Len;
         Name_Buffer.Chars (Prefix_Len + 1) := '.';

         --  Names are stored in lower case so fold them if need be

         if Is_Upper_Case_Letter (Text (Lo)) then
            for J in Lo .. Hi loop
               Name_Buffer.Chars (Prefix_Len + 2 + Integer (J - Lo)) :=
                                                         Fold_Lower (Text (J));
            end loop;

         else
            declare
               S : String (Integer (Lo) .. Integer (Hi));
               for S'Address use Text (Lo)'Address;

            begin
               Name_Buffer.Chars (Prefix_Len + 2 .. Prefix_Len + 1 + Len) := S;
            end;
         end if;

         return Name_Find (Name_Buffer);
      end Read_Name_With_Prefix;

      ------------------
      --  Read_Number --
      ------------------

      function Read_Number return Uint is
         Token_Start : Text_Position;
         Token_End   : Text_Position;

      begin
         --  Only integers are to be expected here

         Read_Token_And_Error (J_INTEGER, Token_Start, Token_End);

         return Decode_Integer (Token_Start.Index, Token_End.Index);
      end Read_Number;

      --------------------------
      --  Read_Numerical_Expr --
      --------------------------

      function Read_Numerical_Expr return Node_Ref_Or_Val is
         Code        : TCode;
         Nop         : Integer;
         Ops         : array (1 .. 3) of Node_Ref_Or_Val;
         TK          : Token_Kind;
         Token_Start : Text_Position;
         Token_End   : Text_Position;

      begin
         --  Read either an integer or an expression

         Read_Token (TK, Token_Start, Token_End);
         if TK = J_INTEGER then
            return Decode_Integer (Token_Start.Index, Token_End.Index);

         elsif TK = J_OBJECT then
            --  Read the code of the expression and decode it

            if Read_String /= Name_Code then
               Error ("name expected");
            end if;

            Read_Token_And_Error (J_STRING, Token_Start, Token_End);
            Code := Decode_Symbol (Token_Start.Index + 1, Token_End.Index - 1);
            Read_Token_And_Error (J_COMMA, Token_Start, Token_End);

            --  Read the array of operands

            if Read_String /= Name_Operands then
               Error ("operands expected");
            end if;

            Read_Token_And_Error (J_ARRAY, Token_Start, Token_End);

            Nop := 0;
            Ops := (others => No_Uint);
            loop
               Nop := Nop + 1;
               Ops (Nop) := Read_Numerical_Expr;
               Read_Token (TK, Token_Start, Token_End);
               if TK = J_ARRAY_END then
                  exit;
               elsif TK /= J_COMMA then
                  Error ("comma expected");
               end if;
            end loop;

            Read_Token_And_Error (J_OBJECT_END, Token_Start, Token_End);

            --  Resolve the ambiguity for '-' now

            if Code = Minus_Expr and then Nop = 1 then
               Code := Negate_Expr;
            end if;

            return Create_Node (Code, Ops (1), Ops (2), Ops (3));

         else
            Error ("numerical expression expected");
         end if;
      end Read_Numerical_Expr;

      -------------------
      --  Read_Record  --
      -------------------

      procedure Read_Record is
         Comp        : JSON_Component_Node;
         First_Bit   : Node_Ref_Or_Val := No_Uint;
         Is_First    : Boolean := True;
         Nam         : Name_Id := No_Name;
         Position    : Node_Ref_Or_Val := No_Uint;
         TK          : Token_Kind;
         Token_Start : Text_Position;
         Token_End   : Text_Position;

      begin
         --  Read a possibly empty array of components

         Read_Token_And_Error (J_ARRAY, Token_Start, Token_End);

         loop
            Read_Token (TK, Token_Start, Token_End);
            if Is_First and then TK = J_ARRAY_END then
               exit;
            elsif TK /= J_OBJECT then
               Error ("object expected");
            end if;

            --  Read the members as string : value pairs

            loop
               case Read_String is
                  when Name_Name =>
                     Nam := Read_Name_With_Prefix;
                  when Name_Discriminant =>
                     Skip_Value;
                  when Name_Position =>
                     Position := Read_Numerical_Expr;
                  when Name_First_Bit =>
                     First_Bit := Read_Number;
                  when Name_Size =>
                     Comp.Esize := Read_Numerical_Expr;
                  when others =>
                     Error ("invalid component");
               end case;

               Read_Token (TK, Token_Start, Token_End);
               if TK = J_OBJECT_END then
                  exit;
               elsif TK /= J_COMMA then
                  Error ("comma expected");
               end if;
            end loop;

            --  Compute Component_Bit_Offset from Position and First_Bit,
            --  either symbolically or literally depending on Position.

            if No (Position) or else No (First_Bit) then
               Error ("bit offset expected");
            end if;

            if Position < Uint_0 then
               declare
                  Bit_Position : constant Node_Ref_Or_Val :=
                          Create_Node (Mult_Expr, Position, UI_From_Int (SSU));
               begin
                  if First_Bit = Uint_0 then
                     Comp.Bit_Offset := Bit_Position;
                  else
                     Comp.Bit_Offset :=
                              Create_Node (Plus_Expr, Bit_Position, First_Bit);
                  end if;
               end;
            else
               Comp.Bit_Offset := Position * SSU + First_Bit;
            end if;

            --  Store the component into the table

            JSON_Component_Table.Append (Comp);

            --  Associate the name with the component

            if Nam = No_Name then
               Error ("name expected");
            end if;

            Set_Name_Table_Int (Nam, JSON_Component_Table.Last);

            Read_Token (TK, Token_Start, Token_End);
            if TK = J_ARRAY_END then
               exit;
            elsif TK /= J_COMMA then
               Error ("comma expected");
            end if;

            Is_First := False;
         end loop;
      end Read_Record;

      ------------------
      --  Read_String --
      ------------------

      function Read_String return Valid_Name_Id is
         Token_Start : Text_Position;
         Token_End   : Text_Position;
         Nam         : Valid_Name_Id;

      begin
         --  Read the string and the following colon

         Read_Token_And_Error (J_STRING, Token_Start, Token_End);
         Nam := Decode_Name (Token_Start.Index + 1, Token_End.Index - 1);
         Read_Token_And_Error (J_COLON, Token_Start, Token_End);

         return Nam;
      end Read_String;

      ------------------
      --  Read_Token  --
      ------------------

      procedure Read_Token
        (Kind        : out Token_Kind;
         Token_Start : out Text_Position;
         Token_End   : out Text_Position)
      is
         procedure Next_Char;
         --  Update Pos to point to next char

         function Is_Whitespace return Boolean;
         pragma Inline (Is_Whitespace);
         --  Return True of current character is a whitespace

         function Is_Structural_Token return Boolean;
         pragma Inline (Is_Structural_Token);
         --  Return True if current character is one of the structural tokens

         function Is_Token_Sep return Boolean;
         pragma Inline (Is_Token_Sep);
         --  Return True if current character is a token separator

         procedure Delimit_Keyword (Kw : String);
         --  Helper function to parse tokens such as null, false and true

         ---------------
         -- Next_Char --
         ---------------

         procedure Next_Char is
         begin
            if Pos.Index > Text'Last then
               Pos.Column := Pos.Column + 1;
            elsif Text (Pos.Index) = ASCII.LF then
               Pos.Column := 1;
               Pos.Line := Pos.Line + 1;
            else
               Pos.Column := Pos.Column + 1;
            end if;
            Pos.Index := Pos.Index + 1;
         end Next_Char;

         -------------------
         -- Is_Whitespace --
         -------------------

         function Is_Whitespace return Boolean is
         begin
            return
              Pos.Index <= Text'Last
                and then
              (Text (Pos.Index) = ASCII.LF
                 or else
               Text (Pos.Index) = ASCII.CR
                 or else
               Text (Pos.Index) = ASCII.HT
                 or else
               Text (Pos.Index) = ' ');
         end Is_Whitespace;

         -------------------------
         -- Is_Structural_Token --
         -------------------------

         function Is_Structural_Token return Boolean is
         begin
            return
              Pos.Index <= Text'Last
                and then
              (Text (Pos.Index) = '['
                 or else
               Text (Pos.Index) = ']'
                 or else
               Text (Pos.Index) = '{'
                 or else
               Text (Pos.Index) = '}'
                 or else
               Text (Pos.Index) = ','
                 or else
               Text (Pos.Index) = ':');
         end Is_Structural_Token;

         ------------------
         -- Is_Token_Sep --
         ------------------

         function Is_Token_Sep return Boolean is
         begin
            return
              Pos.Index > Text'Last
                or else
              Is_Whitespace
                or else
              Is_Structural_Token;
         end Is_Token_Sep;

         ---------------------
         -- Delimit_Keyword --
         ---------------------

         procedure Delimit_Keyword (Kw : String) is
            pragma Unreferenced (Kw);
         begin
            while not Is_Token_Sep loop
               Token_End := Pos;
               Next_Char;
            end loop;
         end Delimit_Keyword;

         CC             : Character;
         Can_Be_Integer : Boolean := True;

      --  Start of processing for Read_Token

      begin
         --  Skip leading whitespaces

         while Is_Whitespace loop
            Next_Char;
         end loop;

         --  Initialize token delimiters

         Token_Start := Pos;
         Token_End   := Pos;

         --  End of stream reached

         if Pos.Index > Text'Last then
            Kind := J_EOF;
            return;
         end if;

         CC := Text (Pos.Index);

         if CC = '[' then
            Next_Char;
            Kind := J_ARRAY;
            return;
         elsif CC = ']' then
            Next_Char;
            Kind := J_ARRAY_END;
            return;
         elsif CC = '{' then
            Next_Char;
            Kind := J_OBJECT;
            return;
         elsif CC = '}' then
            Next_Char;
            Kind := J_OBJECT_END;
            return;
         elsif CC = ',' then
            Next_Char;
            Kind := J_COMMA;
            return;
         elsif CC = ':' then
            Next_Char;
            Kind := J_COLON;
            return;
         elsif CC = 'n' then
            Delimit_Keyword ("null");
            Kind := J_NULL;
            return;
         elsif CC = 'f' then
            Delimit_Keyword ("false");
            Kind := J_FALSE;
            return;
         elsif CC = 't' then
            Delimit_Keyword ("true");
            Kind := J_TRUE;
            return;
         elsif CC = '"' then
            --  We expect a string
            --  Just scan till the end the of the string but do not attempt
            --  to decode it. This means that even if we get a string token
            --  it might not be a valid string from the ECMA 404 point of
            --  view.

            Next_Char;
            while Pos.Index <= Text'Last and then Text (Pos.Index) /= '"' loop
               if Text (Pos.Index) in ASCII.NUL .. ASCII.US then
                  Error ("control character not allowed in string");
               end if;

               if Text (Pos.Index) = '\' then
                  Next_Char;
                  if Pos.Index > Text'Last then
                     Error ("non terminated string token");
                  end if;

                  case Text (Pos.Index) is
                     when 'u' =>
                        for Idx in 1 .. 4 loop
                           Next_Char;
                           if Pos.Index > Text'Last
                             or else (Text (Pos.Index) not in 'a' .. 'f'
                                        and then
                                      Text (Pos.Index) not in 'A' .. 'F'
                                        and then
                                      Text (Pos.Index) not in '0' .. '9')
                           then
                              Error ("invalid unicode escape sequence");
                           end if;
                        end loop;
                     when '\' | '/' | '"' | 'b' | 'f' | 'n' | 'r' | 't' =>
                        null;
                     when others =>
                        Error ("invalid escape sequence");
                  end case;
               end if;
               Next_Char;
            end loop;

            --  No quote found report and error

            if Pos.Index > Text'Last then
               Error ("non terminated string token");
            end if;

            Token_End := Pos;

            --  Go to next char and ensure that this is separator. Indeed
            --  construction such as "string1""string2" are not allowed

            Next_Char;
            if not Is_Token_Sep then
               Error ("invalid syntax");
            end if;
            Kind := J_STRING;
            return;
         elsif CC = '-' or else CC in '0' .. '9' then
            --  We expect a number
            if CC = '-' then
               Next_Char;
            end if;

            if Pos.Index > Text'Last then
               Error ("invalid number");
            end if;

            --  Parse integer part of a number. Superfluous leading zeros are
            --  not allowed.

            if Text (Pos.Index) = '0' then
               Token_End := Pos;
               Next_Char;
            elsif Text (Pos.Index) in '1' .. '9' then
               Token_End := Pos;
               Next_Char;
               while Pos.Index <= Text'Last
                 and then Text (Pos.Index) in '0' .. '9'
               loop
                  Token_End := Pos;
                  Next_Char;
               end loop;
            else
               Error ("invalid number");
            end if;

            if Is_Token_Sep then
               --  Valid integer number

               Kind := J_INTEGER;
               return;
            elsif Text (Pos.Index) /= '.'
              and then Text (Pos.Index) /= 'e'
              and then Text (Pos.Index) /= 'E'
            then
               Error ("invalid number");
            end if;

            --  Check for a fractional part

            if Text (Pos.Index) = '.' then
               Can_Be_Integer := False;
               Token_End := Pos;
               Next_Char;
               if Pos.Index > Text'Last
                 or else Text (Pos.Index) not in '0' .. '9'
               then
                  Error ("invalid number");
               end if;

               while Pos.Index <= Text'Last
                 and then Text (Pos.Index) in '0' .. '9'
               loop
                  Token_End := Pos;
                  Next_Char;
               end loop;

            end if;

            --  Check for exponent part

            if Pos.Index <= Text'Last
              and then (Text (Pos.Index) = 'e' or else Text (Pos.Index) = 'E')
            then
               Token_End := Pos;
               Next_Char;
               if Pos.Index > Text'Last then
                  Error ("invalid number");
               end if;

               if Text (Pos.Index) = '-' then
                  --  Also a few corner cases can lead to an integer, assume
                  --  that the number is not an integer.

                  Can_Be_Integer := False;
               end if;

               if Text (Pos.Index) = '-' or else Text (Pos.Index) = '+' then
                  Next_Char;
               end if;

               if Pos.Index > Text'Last
                 or else Text (Pos.Index) not in '0' .. '9'
               then
                  Error ("invalid number");
               end if;

               while Pos.Index <= Text'Last
                 and then Text (Pos.Index) in '0' .. '9'
               loop
                  Token_End := Pos;
                  Next_Char;
               end loop;
            end if;

            if Is_Token_Sep then
               --  Valid decimal number

               if Can_Be_Integer then
                  Kind := J_INTEGER;
               else
                  Kind := J_NUMBER;
               end if;
               return;
            else
               Error ("invalid number");
            end if;
         elsif CC = EOF then
            Kind := J_EOF;
         else
            Error ("Unexpected character");
         end if;
      end Read_Token;

      ----------------------------
      --  Read_Token_And_Error  --
      ----------------------------

      procedure Read_Token_And_Error
        (TK          : Token_Kind;
         Token_Start : out Text_Position;
         Token_End   : out Text_Position)
      is
         Kind : Token_Kind;

      begin
         --  Read a token and errout out if not of the expected kind

         Read_Token (Kind, Token_Start, Token_End);
         if Kind /= TK then
            Error ("specific token expected");
         end if;
      end Read_Token_And_Error;

      -------------------------
      --  Read_Variant_Part  --
      -------------------------

      function Read_Variant_Part return Nat is
         Next        : Nat := 0;
         TK          : Token_Kind;
         Token_Start : Text_Position;
         Token_End   : Text_Position;
         Var         : JSON_Variant_Node;

      begin
         --  Read a nonempty array of components

         Read_Token_And_Error (J_ARRAY, Token_Start, Token_End);

         loop
            Read_Token_And_Error (J_OBJECT, Token_Start, Token_End);

            Var.Variant := 0;

            --  Read the members as string : value pairs

            loop
               case Read_String is
                  when Name_Present =>
                     Var.Present := Read_Numerical_Expr;
                  when Name_Record =>
                     Read_Record;
                  when Name_Variant =>
                     Var.Variant := Read_Variant_Part;
                  when others =>
                     Error ("invalid variant");
               end case;

               Read_Token (TK, Token_Start, Token_End);
               if TK = J_OBJECT_END then
                  exit;
               elsif TK /= J_COMMA then
                  Error ("comma expected");
               end if;
            end loop;

            --  Chain the variant and store it into the table

            Var.Next := Next;
            JSON_Variant_Table.Append (Var);
            Next := JSON_Variant_Table.Last;

            Read_Token (TK, Token_Start, Token_End);
            if TK = J_ARRAY_END then
               exit;
            elsif TK /= J_COMMA then
               Error ("comma expected");
            end if;
         end loop;

         return Next;
      end Read_Variant_Part;

      ------------------
      --  Skip_Value  --
      ------------------

      procedure Skip_Value is
         Array_Depth  : Natural := 0;
         Object_Depth : Natural := 0;
         TK           : Token_Kind;
         Token_Start  : Text_Position;
         Token_End    : Text_Position;

      begin
         --  Read a value without recursing

         loop
            Read_Token (TK, Token_Start, Token_End);

            case TK is
               when J_STRING | J_INTEGER | J_NUMBER =>
                  null;
               when J_ARRAY =>
                  Array_Depth := Array_Depth + 1;
               when J_ARRAY_END =>
                  Array_Depth := Array_Depth - 1;
               when J_OBJECT =>
                  Object_Depth := Object_Depth + 1;
               when J_OBJECT_END =>
                  Object_Depth := Object_Depth - 1;
               when J_COLON | J_COMMA =>
                  if Array_Depth = 0 and then Object_Depth = 0 then
                     Error ("value expected");
                  end if;
               when others =>
                  Error ("value expected");
            end case;

            exit when Array_Depth = 0 and then Object_Depth = 0;
         end loop;
      end Skip_Value;

      Token_Start : Text_Position;
      Token_End   : Text_Position;
      TK          : Token_Kind;
      Is_First    : Boolean := True;

   --  Start of processing for Read_JSON_Stream

   begin
      --  Read a possibly empty array of entities

      Read_Token_And_Error (J_ARRAY, Token_Start, Token_End);

      loop
         Read_Token (TK, Token_Start, Token_End);
         if Is_First and then TK = J_ARRAY_END then
            exit;
         elsif TK /= J_OBJECT then
            Error ("object expected");
         end if;

         Read_Entity;

         Read_Token (TK, Token_Start, Token_End);
         if TK = J_ARRAY_END then
            exit;
         elsif TK /= J_COMMA then
            Error ("comma expected");
         end if;

         Is_First := False;
      end loop;
   end Read_JSON_Stream;

end Repinfo.Input;
