Fix legacy_fields_migrator

Another round of fixes:

* if the toolchain contains legacy_compile_flags or legacy_link_flags, replace the feature with default_compile_flags or default_link_flags. This is to ensure the location of the flags stays intact.
* it fixes the order of compilation flags, the correct order is:
  1) compiler_flag
  2) compilation_mode_flags.compiler_flag
  3) cxx_flag
  4) compilation_mode_flags.cxx_flag
* We don't add cxx_flags to assemble and preprocess-assemble actions
* We don't add sysroot to assemble action

https://github.com/bazelbuild/bazel/issues/6861
https://github.com/bazelbuild/bazel/issues/5883

RELNOTES: None.
PiperOrigin-RevId: 229336027
diff --git a/tools/migration/legacy_fields_migration_lib.py b/tools/migration/legacy_fields_migration_lib.py
index f761847..9b42d14 100644
--- a/tools/migration/legacy_fields_migration_lib.py
+++ b/tools/migration/legacy_fields_migration_lib.py
@@ -25,7 +25,8 @@
 ]
 
 ALL_CXX_COMPILE_ACTIONS = [
-    action for action in ALL_CC_COMPILE_ACTIONS if action != "c-compile"
+    action for action in ALL_CC_COMPILE_ACTIONS
+    if action not in ["c-compile", "preprocess-assemble", "assemble"]
 ]
 
 ALL_CC_LINK_ACTIONS = [
@@ -44,16 +45,16 @@
 def compile_actions(toolchain):
   """Returns compile actions for cc or objc rules."""
   if _is_objc_toolchain(toolchain):
-      return ALL_CC_COMPILE_ACTIONS + ALL_OBJC_COMPILE_ACTIONS
+    return ALL_CC_COMPILE_ACTIONS + ALL_OBJC_COMPILE_ACTIONS
   else:
-      return ALL_CC_COMPILE_ACTIONS
+    return ALL_CC_COMPILE_ACTIONS
 
 def link_actions(toolchain):
   """Returns link actions for cc or objc rules."""
   if _is_objc_toolchain(toolchain):
-      return ALL_CC_LINK_ACTIONS + ALL_OBJC_LINK_ACTIONS
+    return ALL_CC_LINK_ACTIONS + ALL_OBJC_LINK_ACTIONS
   else:
-      return ALL_CC_LINK_ACTIONS
+    return ALL_CC_LINK_ACTIONS
 
 def _is_objc_toolchain(toolchain):
   return any(ac.action_name == "objc-compile" for ac in toolchain.action_config)
@@ -172,7 +173,14 @@
     if flag_sets:
       if _contains_feature(toolchain, "default_link_flags"):
         continue
-      feature = _prepend_feature(toolchain)
+      if _contains_feature(toolchain, "legacy_link_flags"):
+        for f in toolchain.feature:
+          if f.name == "legacy_link_flags":
+            f.ClearField("flag_set")
+            feature = f
+            break
+      else:
+        feature = _prepend_feature(toolchain)
       feature.name = "default_link_flags"
       feature.enabled = True
       _add_flag_sets(feature, flag_sets)
@@ -180,7 +188,14 @@
     # Create default_compile_flags feature for compiler_flag, cxx_flag
     flag_sets = _extract_legacy_compile_flag_sets_for(toolchain)
     if flag_sets and not _contains_feature(toolchain, "default_compile_flags"):
-      feature = _prepend_feature(toolchain)
+      if _contains_feature(toolchain, "legacy_compile_flags"):
+        for f in toolchain.feature:
+          if f.name == "legacy_compile_flags":
+            f.ClearField("flag_set")
+            feature = f
+            break
+      else:
+        feature = _prepend_feature(toolchain)
       feature.enabled = True
       feature.name = "default_compile_flags"
       _add_flag_sets(feature, flag_sets)
@@ -214,11 +229,13 @@
           flag_group.flag[:] = ["%{user_compile_flags}"]
 
         if not _contains_feature(toolchain, "sysroot"):
+          sysroot_actions = compile_actions(toolchain) + link_actions(toolchain)
+          sysroot_actions.remove("assemble")
           feature = toolchain.feature.add()
           feature.name = "sysroot"
           feature.enabled = True
           flag_set = feature.flag_set.add()
-          flag_set.action[:] = compile_actions(toolchain) + link_actions(toolchain)
+          flag_set.action[:] = sysroot_actions
           flag_group = flag_set.flag_group.add()
           flag_group.expand_if_all_available[:] = ["sysroot"]
           flag_group.flag[:] = ["--sysroot=%{sysroot}"]
@@ -293,10 +310,8 @@
   result = []
   if toolchain.compiler_flag:
     result.append([None, compile_actions(toolchain), toolchain.compiler_flag, []])
-  if toolchain.cxx_flag:
-    result.append([None, ALL_CXX_COMPILE_ACTIONS, toolchain.cxx_flag, []])
 
-  # Migrate compiler_flag/cxx_flag from compilation_mode_flags
+  # Migrate compiler_flag from compilation_mode_flags
   for cmf in toolchain.compilation_mode_flags:
     mode = crosstool_config_pb2.CompilationMode.Name(cmf.mode).lower()
     # coverage mode has been a noop since a while
@@ -311,6 +326,16 @@
     if cmf.compiler_flag:
       result.append([mode, compile_actions(toolchain), cmf.compiler_flag, []])
 
+  if toolchain.cxx_flag:
+    result.append([None, ALL_CXX_COMPILE_ACTIONS, toolchain.cxx_flag, []])
+
+  # Migrate compiler_flag/cxx_flag from compilation_mode_flags
+  for cmf in toolchain.compilation_mode_flags:
+    mode = crosstool_config_pb2.CompilationMode.Name(cmf.mode).lower()
+    # coverage mode has been a noop since a while
+    if mode == "coverage":
+      continue
+
     if cmf.cxx_flag:
       result.append([mode, ALL_CXX_COMPILE_ACTIONS, cmf.cxx_flag, []])
 
diff --git a/tools/migration/legacy_fields_migration_lib_test.py b/tools/migration/legacy_fields_migration_lib_test.py
index eaa4317..ee127fa 100644
--- a/tools/migration/legacy_fields_migration_lib_test.py
+++ b/tools/migration/legacy_fields_migration_lib_test.py
@@ -87,6 +87,37 @@
     migrate_legacy_fields(crosstool)
     self.assertEqual(len(crosstool.default_toolchain), 0)
 
+  def test_replace_legacy_compile_flags(self):
+    crosstool = make_crosstool("""
+        feature { name: 'foo' }
+        feature { name: 'legacy_compile_flags' }
+        compiler_flag: 'clang-flag-1'
+    """)
+    migrate_legacy_fields(crosstool)
+    output = crosstool.toolchain[0]
+    self.assertEqual(len(output.compiler_flag), 0)
+    self.assertEqual(output.feature[0].name, "foo")
+    self.assertEqual(output.feature[1].name, "default_compile_flags")
+    self.assertEqual(output.feature[1].flag_set[0].action,
+                     ALL_CC_COMPILE_ACTIONS)
+    self.assertEqual(output.feature[1].flag_set[0].flag_group[0].flag,
+                     ["clang-flag-1"])
+
+  def test_replace_legacy_link_flags(self):
+    crosstool = make_crosstool("""
+        feature { name: 'foo' }
+        feature { name: 'legacy_link_flags' }
+        linker_flag: 'ld-flag-1'
+    """)
+    migrate_legacy_fields(crosstool)
+    output = crosstool.toolchain[0]
+    self.assertEqual(len(output.compiler_flag), 0)
+    self.assertEqual(output.feature[0].name, "foo")
+    self.assertEqual(output.feature[1].name, "default_link_flags")
+    self.assertEqual(output.feature[1].flag_set[0].action, ALL_CC_LINK_ACTIONS)
+    self.assertEqual(output.feature[1].flag_set[0].flag_group[0].flag,
+                     ["ld-flag-1"])
+
   def test_migrate_compiler_flags(self):
     crosstool = make_crosstool("""
         compiler_flag: 'clang-flag-1'
@@ -191,18 +222,18 @@
     self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
                      ["compile-flag-1"])
 
-    # flag set for cxx_flag fields
-    self.assertEqual(len(output.feature[0].flag_set[1].with_feature), 0)
-    self.assertEqual(output.feature[0].flag_set[1].flag_group[0].flag,
-                     ["cxx-flag-1"])
-
     # flag set for compiler_flag from compilation_mode_flags
-    self.assertEqual(len(output.feature[0].flag_set[2].with_feature), 1)
-    self.assertEqual(output.feature[0].flag_set[2].with_feature[0].feature[0],
+    self.assertEqual(len(output.feature[0].flag_set[1].with_feature), 1)
+    self.assertEqual(output.feature[0].flag_set[1].with_feature[0].feature[0],
                      "opt")
-    self.assertEqual(output.feature[0].flag_set[2].flag_group[0].flag,
+    self.assertEqual(output.feature[0].flag_set[1].flag_group[0].flag,
                      ["opt-flag-1"])
 
+    # flag set for cxx_flag fields
+    self.assertEqual(len(output.feature[0].flag_set[2].with_feature), 0)
+    self.assertEqual(output.feature[0].flag_set[2].flag_group[0].flag,
+                     ["cxx-flag-1"])
+
     # flag set for cxx_flag from compilation_mode_flags
     self.assertEqual(len(output.feature[0].flag_set[3].with_feature), 1)
     self.assertEqual(output.feature[0].flag_set[3].with_feature[0].feature[0],
@@ -464,6 +495,9 @@
                      ["%{user_compile_flags}"])
 
   def test_sysroot(self):
+    sysroot_actions = ALL_CC_COMPILE_ACTIONS + ALL_CC_LINK_ACTIONS
+    sysroot_actions.remove("assemble")
+    self.assertTrue("assemble" not in sysroot_actions)
     crosstool = make_crosstool("""
       unfiltered_cxx_flag: 'unfiltered-flag-1'
     """)
@@ -471,8 +505,7 @@
     output = crosstool.toolchain[0]
     self.assertEqual(output.feature[1].name, "sysroot")
     self.assertEqual(output.feature[1].enabled, True)
-    self.assertEqual(output.feature[1].flag_set[0].action,
-                     ALL_CC_COMPILE_ACTIONS + ALL_CC_LINK_ACTIONS)
+    self.assertEqual(output.feature[1].flag_set[0].action, sysroot_actions)
     self.assertEqual(
         output.feature[1].flag_set[0].flag_group[0].expand_if_all_available,
         ["sysroot"])