vss_24.0.0_b4d0be7c/tools/json_schema/json_schema-driver.adb

  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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
--
--  Copyright (C) 2022, AdaCore
--
--  SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
--

with Ada.Streams.Stream_IO;
with Ada.Wide_Wide_Text_IO;

with VSS.Application;
with VSS.JSON.Pull_Readers.Simple;
with VSS.Stream_Element_Vectors;
with VSS.Strings.Conversions;
with VSS.Text_Streams.Memory_UTF8_Input;
with VSS.String_Vectors;

with JSON_Schema.Readers;
with JSON_Schema.Writers.Types;

procedure JSON_Schema.Driver is

   function Parse_Command_Line return Boolean;
   --  Parse application arguments and return True if success.

   procedure Read_File
     (File_Name : VSS.Strings.Virtual_String;
      Value     : out VSS.String_Vectors.Virtual_String_Vector);
   --  Read lines from given file into a string vector

   Arg          : VSS.Strings.Virtual_String;
   --  JSON Schema input file
   Root_Package : VSS.Strings.Virtual_String := "Types";
   --  Name of a root package
   Enum_Package : VSS.Strings.Virtual_String;
   --  Name of dedicated package for enumeration types, could be useful to
   --  avoid name clashes.
   Header_File  : VSS.Strings.Virtual_String;
   --  Header file - copyright/license to put on top of each file
   Holders      : VSS.String_Vectors.Virtual_String_Vector;
   --  Array of "holder" fields in form of "type:field" where a holder type
   --  should be used instead of type.

   ------------------------
   -- Parse_Command_Line --
   ------------------------

   function Parse_Command_Line return Boolean is
      use type VSS.Strings.Virtual_String;
      Is_Root_Package : Boolean := False;
      Is_Enum_Package : Boolean := False;
      Is_Header_File  : Boolean := False;
      Is_Holder       : Boolean := False;
   begin
      for Item of VSS.Application.Arguments loop
         if Is_Root_Package then
            Is_Root_Package := False;
            Root_Package := Item;
         elsif Is_Enum_Package then
            Is_Enum_Package := False;
            Enum_Package := Item;
         elsif Is_Header_File then
            Is_Header_File := False;
            Header_File := Item;
         elsif Is_Holder then
            Is_Holder := False;
            Holders.Append (Item);
         elsif Item = "--root-package" then
            Is_Root_Package := True;
         elsif Item = "--enum-package" then
            Is_Enum_Package := True;
         elsif Item = "--header-file" then
            Is_Header_File := True;
         elsif Item = "--holder" then
            Is_Holder := True;
         else
            Arg := Item;
         end if;
      end loop;

      return not Arg.Is_Empty
        and not Is_Header_File
        and not Is_Holder
        and not Is_Root_Package
        and not Is_Enum_Package;
   end Parse_Command_Line;

   procedure Read_File
     (File_Name : VSS.Strings.Virtual_String;
      Value     : out VSS.String_Vectors.Virtual_String_Vector)
   is
      Input : Ada.Wide_Wide_Text_IO.File_Type;
   begin
      Ada.Wide_Wide_Text_IO.Open
       (Input,
        Ada.Wide_Wide_Text_IO.In_File,
        VSS.Strings.Conversions.To_UTF_8_String (File_Name));

      while not Ada.Wide_Wide_Text_IO.End_Of_File (Input) loop
         declare
            Line : constant Wide_Wide_String :=
              Ada.Wide_Wide_Text_IO.Get_Line (Input);
         begin
            Value.Append (VSS.Strings.To_Virtual_String (Line));
         end;
      end loop;

      Ada.Wide_Wide_Text_IO.Close (Input);
   end Read_File;

   File  : Ada.Streams.Stream_IO.File_Type;
   Raw   : VSS.Stream_Element_Vectors.Stream_Element_Vector;
   Input : aliased VSS.Text_Streams.Memory_UTF8_Input.Memory_UTF8_Input_Stream;

   Header : VSS.String_Vectors.Virtual_String_Vector;
   Reader : VSS.JSON.Pull_Readers.Simple.JSON_Simple_Pull_Reader;
   Schema : JSON_Schema.Schema_Access;
   Other  : JSON_Schema.Readers.Schema_Map;
begin
   if not Parse_Command_Line then
      Ada.Wide_Wide_Text_IO.Put_Line
       ("Usage: gen_json [options] <json_schema>.json");
      Ada.Wide_Wide_Text_IO.New_Line;
      Ada.Wide_Wide_Text_IO.Put_Line ("Where options:");
      Ada.Wide_Wide_Text_IO.Put_Line
        ("  --root-package <package> - A package for generated types");
      Ada.Wide_Wide_Text_IO.Put_Line
        ("  --enum-package <package> - A package for enumeration types");
      Ada.Wide_Wide_Text_IO.Put_Line
        ("  --header-file  <file>    - A copyright header file");
      Ada.Wide_Wide_Text_IO.Put_Line
        ("  --holder <type:field>    - Use holder to break circular " &
         "dependency");
      return;
   end if;

   if not Header_File.Is_Empty then
      Read_File (Header_File, Header);
      Header.Append ("");
   end if;

   Ada.Streams.Stream_IO.Open
     (File,
      Ada.Streams.Stream_IO.In_File,
      VSS.Strings.Conversions.To_UTF_8_String (Arg));

   while not Ada.Streams.Stream_IO.End_Of_File (File) loop
      declare
         Data : Ada.Streams.Stream_Element_Array (1 .. 256);
         Last : Ada.Streams.Stream_Element_Offset;
      begin
         Ada.Streams.Stream_IO.Read (File, Data, Last);
         for X of Data (1 .. Last) loop
            Raw.Append (X);
         end loop;
      end;
   end loop;

   Input.Set_Data (Raw);
   Reader.Set_Stream (Input'Unchecked_Access);
   Reader.Read_Next;
   pragma Assert (Reader.Is_Start_Document);
   Reader.Read_Next;

   JSON_Schema.Readers.Read (Reader, Schema, Other);
   JSON_Schema.Writers.Types.Write
     (Other, Root_Package, Enum_Package, Header, Holders);
end JSON_Schema.Driver;