-------------------------------------------------------------------------------
-- (C) Altran Praxis Limited
-------------------------------------------------------------------------------
--
-- The SPARK toolset is free software; you can redistribute it and/or modify it
-- under terms of the GNU General Public License as published by the Free
-- Software Foundation; either version 3, or (at your option) any later
-- version. The SPARK toolset is distributed in the hope that it will be
-- useful, but WITHOUT 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 the SPARK toolset; see file
-- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy of
-- the license.
--
--=============================================================================

separate (Sem.Wf_Package_Declaration)
procedure Get_Package_Declaration_Key_Nodes
  (Node                        : in     STree.SyntaxNode;
   Context_Node                :    out STree.SyntaxNode;
   Inherit_Node                :    out STree.SyntaxNode;
   Generic_Formal_Part_Node    :    out STree.SyntaxNode;
   Spec_Node                   :    out STree.SyntaxNode;
   Ident_Node                  :    out STree.SyntaxNode;
   Private_Package_Declaration :    out Boolean;
   Child_Package_Declaration   :    out Boolean)
is
begin
   Context_Node := Parent_Node (Current_Node => Node);
   -- ASSUME Context_Node = library_unit OR initial_declarative_item_rep OR generic_declaration
   if Syntax_Node_Type (Node => Context_Node) = SP_Symbols.library_unit
     or else Syntax_Node_Type (Node => Context_Node) = SP_Symbols.generic_declaration then
      -- ASSUME Context_Node = library_unit OR generic_declaration
      if Syntax_Node_Type (Node => Context_Node) = SP_Symbols.generic_declaration then
         -- ASSUME Context_Node = generic_declaration
         Context_Node := Parent_Node (Current_Node => Context_Node);
      end if;
      -- ASSUME Context_Node = library_unit
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => Context_Node) = SP_Symbols.library_unit,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Context_Node = library_unit in Get_Package_Declaration_Key_Nodes");
      Context_Node := Child_Node (Current_Node => Parent_Node (Current_Node => Context_Node));
      -- ASSUME Context_Node = context_clause OR library_unit
      if Syntax_Node_Type (Node => Context_Node) = SP_Symbols.library_unit then
         -- ASSUME Context_Node = library_unit
         Context_Node := STree.NullNode;
      elsif Syntax_Node_Type (Node => Context_Node) /= SP_Symbols.context_clause then
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Context_Node = context_clause OR library_unit in Get_Package_Declaration_Key_Nodes");
      end if;
   elsif Syntax_Node_Type (Node => Context_Node) = SP_Symbols.initial_declarative_item_rep then
      -- ASSUME Context_Node = initial_declarative_item_rep
      Context_Node := STree.NullNode;
   else
      SystemErrors.Fatal_Error
        (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Context_Node = library_unit OR initial_declarative_item_rep OR generic_declaration " &
           " in Get_Package_Declaration_Key_Nodes");
   end if;
   -- ASSUME Context_Node = context_clause OR NULL
   SystemErrors.RT_Assert
     (C       => Context_Node = STree.NullNode or else Syntax_Node_Type (Node => Context_Node) = SP_Symbols.context_clause,
      Sys_Err => SystemErrors.Invalid_Syntax_Tree,
      Msg     => "Expect Context_Node = context_clause OR NULL in Get_Package_Declaration_Key_Nodes");

   Private_Package_Declaration := Syntax_Node_Type (Node => Node) = SP_Symbols.private_package_declaration;
   Inherit_Node                := Child_Node (Current_Node => Node);
   -- ASSUME Inherit_Node = inherit_clause OR generic_formal_part OR package_specification
   if Syntax_Node_Type (Node => Inherit_Node) = SP_Symbols.inherit_clause then
      -- ASSUME Inherit_Node = inherit_clause
      Generic_Formal_Part_Node := Next_Sibling (Current_Node => Inherit_Node);
      -- ASSUME Generic_Formal_Part_Node = generic_formal_part OR package_specification
      if Syntax_Node_Type (Node => Generic_Formal_Part_Node) = SP_Symbols.generic_formal_part then
         -- ASSUME Generic_Formal_Part_Node = generic_formal_part
         Spec_Node := Next_Sibling (Current_Node => Generic_Formal_Part_Node);
      elsif Syntax_Node_Type (Node => Generic_Formal_Part_Node) = SP_Symbols.package_specification then
         -- ASSUME Generic_Formal_Part_Node = package_specification
         Spec_Node                := Generic_Formal_Part_Node;
         Generic_Formal_Part_Node := STree.NullNode;
      else
         Generic_Formal_Part_Node := STree.NullNode;
         Spec_Node                := STree.NullNode;
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Generic_Formal_Part_Node = generic_formal_part OR package_specification" &
              " in Get_Package_Declaration_Key_Nodes");
      end if;
   elsif Syntax_Node_Type (Node => Inherit_Node) = SP_Symbols.generic_formal_part then
      -- ASSUME Inherit_Node = generic_formal_part
      Generic_Formal_Part_Node := Inherit_Node;
      Inherit_Node             := STree.NullNode;
      Spec_Node                := Next_Sibling (Current_Node => Generic_Formal_Part_Node);
   elsif Syntax_Node_Type (Node => Inherit_Node) = SP_Symbols.package_specification then
      -- ASSUME Inherit_Node = package_specification
      Spec_Node                := Inherit_Node;
      Inherit_Node             := STree.NullNode;
      Generic_Formal_Part_Node := STree.NullNode;
   else
      Inherit_Node             := STree.NullNode;
      Generic_Formal_Part_Node := STree.NullNode;
      Spec_Node                := STree.NullNode;
      SystemErrors.Fatal_Error
        (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Inherit_Node = inherit_clause OR generic_formal_part OR package_specification" &
           " in Get_Package_Declaration_Key_Nodes");
   end if;
   -- ASSUME Inherit_Node = inherit_clause OR NULL
   SystemErrors.RT_Assert
     (C       => Inherit_Node = STree.NullNode or else Syntax_Node_Type (Node => Inherit_Node) = SP_Symbols.inherit_clause,
      Sys_Err => SystemErrors.Invalid_Syntax_Tree,
      Msg     => "Expect Inherit_Node = inherit_clause OR NULL in Get_Package_Declaration_Key_Nodes");
   -- ASSUME Generic_Formal_Part_Node = generic_formal_part OR NULL
   SystemErrors.RT_Assert
     (C       => Generic_Formal_Part_Node = STree.NullNode
        or else Syntax_Node_Type (Node => Generic_Formal_Part_Node) = SP_Symbols.generic_formal_part,
      Sys_Err => SystemErrors.Invalid_Syntax_Tree,
      Msg     => "Expect Generic_Formal_Part_Node = generic_formal_part OR NULL in Get_Package_Declaration_Key_Nodes");
   -- ASSUME Spec_Node = package_specification
   SystemErrors.RT_Assert
     (C       => Syntax_Node_Type (Node => Spec_Node) = SP_Symbols.package_specification,
      Sys_Err => SystemErrors.Invalid_Syntax_Tree,
      Msg     => "Expect Spec_Node = package_specification in Get_Package_Declaration_Key_Nodes");

   Ident_Node := Child_Node (Current_Node => Child_Node (Current_Node => Spec_Node));
   -- ASSUME Ident_Node = dotted_simple_name OR identifier
   if Syntax_Node_Type (Node => Ident_Node) = SP_Symbols.identifier then
      -- ASSUME Ident_Node = identifier
      Child_Package_Declaration := False;
   elsif Syntax_Node_Type (Node => Ident_Node) = SP_Symbols.dotted_simple_name then
      -- ASSUME Ident_Node = dotted_simple_name
      Child_Package_Declaration := True;
      Ident_Node                := Last_Child_Of (Start_Node => Ident_Node);
   else
      Child_Package_Declaration := False;
      SystemErrors.Fatal_Error
        (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Ident_Node = dotted_simple_name OR identifier in Get_Package_Declaration_Key_Nodes");
   end if;
   -- ASSUME Ident_Node = identifier
   SystemErrors.RT_Assert
     (C       => Syntax_Node_Type (Node => Ident_Node) = SP_Symbols.identifier,
      Sys_Err => SystemErrors.Invalid_Syntax_Tree,
      Msg     => "Expect Ident_Node = identifier in Get_Package_Declaration_Key_Nodes");
end Get_Package_Declaration_Key_Nodes;
