SourceTestPlan: Move from Requirements to list of Starlark files.

- Based on decisions in
https://docs.google.com/document/d/1xs5kaex3JuMefkWNyUNbLftVz6UjPytzV_2nVHoEk5A/edit?resourcekey=0-MTiOMXXtFArYnM-XUe5LAg#heading=h.weijagth6kz9
and go/cros-testing-config-alignment, DIR_METADATA files will
specify Starlark files to evaluate to generate HW/VMTestPlan protos.

- Requirements fields are currently read, will remove usages and
then remove from proto schema.

BUG=b:182898188
TEST=CQ

Change-Id: I3b6d1d92a948e82d682f8ddb66c7968bcb8e4b91
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/config/+/3209009
Reviewed-by: Sean McAllister <smcallis@google.com>
Reviewed-by: Tim Bain <tbain@google.com>
Commit-Queue: Andrew Lamb <andrewlamb@chromium.org>
diff --git a/generated/descriptors.json b/generated/descriptors.json
index 5062e9e..8f9bbb7 100644
--- a/generated/descriptors.json
+++ b/generated/descriptors.json
@@ -15831,6 +15831,9 @@
               "label": "LABEL_REPEATED",
               "name": "enabled_test_environments",
               "number": 1,
+              "options": {
+                "deprecated": true
+              },
               "type": "TYPE_ENUM",
               "typeName": ".chromiumos.test.plan.SourceTestPlan.TestEnvironment"
             },
@@ -15849,10 +15852,21 @@
               "type": "TYPE_STRING"
             },
             {
+              "jsonName": "testPlanStarlarkFiles",
+              "label": "LABEL_REPEATED",
+              "name": "test_plan_starlark_files",
+              "number": 15,
+              "type": "TYPE_MESSAGE",
+              "typeName": ".chromiumos.test.plan.SourceTestPlan.TestPlanStarlarkFile"
+            },
+            {
               "jsonName": "testTags",
               "label": "LABEL_REPEATED",
               "name": "test_tags",
               "number": 4,
+              "options": {
+                "deprecated": true
+              },
               "type": "TYPE_STRING"
             },
             {
@@ -15860,6 +15874,9 @@
               "label": "LABEL_REPEATED",
               "name": "test_tag_excludes",
               "number": 5,
+              "options": {
+                "deprecated": true
+              },
               "type": "TYPE_STRING"
             },
             {
@@ -15867,6 +15884,9 @@
               "label": "LABEL_OPTIONAL",
               "name": "requirements",
               "number": 13,
+              "options": {
+                "deprecated": true
+              },
               "type": "TYPE_MESSAGE",
               "typeName": ".chromiumos.test.plan.SourceTestPlan.Requirements"
             }
@@ -15876,6 +15896,25 @@
             {
               "field": [
                 {
+                  "jsonName": "repo",
+                  "label": "LABEL_OPTIONAL",
+                  "name": "repo",
+                  "number": 1,
+                  "type": "TYPE_STRING"
+                },
+                {
+                  "jsonName": "path",
+                  "label": "LABEL_OPTIONAL",
+                  "name": "path",
+                  "number": 2,
+                  "type": "TYPE_STRING"
+                }
+              ],
+              "name": "TestPlanStarlarkFile"
+            },
+            {
+              "field": [
+                {
                   "jsonName": "kernelVersions",
                   "label": "LABEL_OPTIONAL",
                   "name": "kernel_versions",
diff --git a/go/test/plan/source_test_plan.pb.go b/go/test/plan/source_test_plan.pb.go
index daceb07..25f7b88 100644
--- a/go/test/plan/source_test_plan.pb.go
+++ b/go/test/plan/source_test_plan.pb.go
@@ -49,23 +49,15 @@
 	return fileDescriptor_28090e75a41618a0, []int{0, 0}
 }
 
-// Describes the test cases, software requirements, and hardware requirements
-// that run when a given set of files are changed.
-//
-// This message contains high-level rules for test planning, e.g. "test on all
-// kernel versions". This is then evaluated into a Specification message which
-// contains attributes that must be tested; in the above example, this would be
-// a list of kernel versions used by ChromeOS.
+// Describes the test cases that run when a given set of files are changed.
 //
 // This message is intended to be specified as text proto in a DIR_METADATA file
 // in the source tree, and should be concise enough Starlark, or another config
 // generation tool, is not needed.
 //
-// NEXT ID: 14
+// NEXT ID: 15
 type SourceTestPlan struct {
-	// Test environments enabled for the test plan. Must contain at least one
-	// test type.
-	EnabledTestEnvironments []SourceTestPlan_TestEnvironment `protobuf:"varint,1,rep,packed,name=enabled_test_environments,json=enabledTestEnvironments,proto3,enum=chromiumos.test.plan.SourceTestPlan_TestEnvironment" json:"enabled_test_environments,omitempty"`
+	EnabledTestEnvironments []SourceTestPlan_TestEnvironment `protobuf:"varint,1,rep,packed,name=enabled_test_environments,json=enabledTestEnvironments,proto3,enum=chromiumos.test.plan.SourceTestPlan_TestEnvironment" json:"enabled_test_environments,omitempty"` // Deprecated: Do not use.
 	// Paths that will trigger the SourceTestPlan.
 	//
 	// Must be a repo-absolute ChromeOS path. For example,
@@ -85,13 +77,15 @@
 	// excluded.
 	PathRegexps        []string `protobuf:"bytes,2,rep,name=path_regexps,json=pathRegexps,proto3" json:"path_regexps,omitempty"`
 	PathRegexpExcludes []string `protobuf:"bytes,3,rep,name=path_regexp_excludes,json=pathRegexpExcludes,proto3" json:"path_regexp_excludes,omitempty"`
+	// Starlark files to evaluate to generate HW/VMTestPlan protos.
+	TestPlanStarlarkFiles []*SourceTestPlan_TestPlanStarlarkFile `protobuf:"bytes,15,rep,name=test_plan_starlark_files,json=testPlanStarlarkFiles,proto3" json:"test_plan_starlark_files,omitempty"`
 	// Only run tests that have at least one of test_tags (if specified) and do
 	// not have any of test_tag_excludes.
 	//
 	// Tags must match exactly (i.e. no regexp, wildcard, etc. allowed).
-	TestTags             []string                     `protobuf:"bytes,4,rep,name=test_tags,json=testTags,proto3" json:"test_tags,omitempty"`
-	TestTagExcludes      []string                     `protobuf:"bytes,5,rep,name=test_tag_excludes,json=testTagExcludes,proto3" json:"test_tag_excludes,omitempty"`
-	Requirements         *SourceTestPlan_Requirements `protobuf:"bytes,13,opt,name=requirements,proto3" json:"requirements,omitempty"`
+	TestTags             []string                     `protobuf:"bytes,4,rep,name=test_tags,json=testTags,proto3" json:"test_tags,omitempty"`                        // Deprecated: Do not use.
+	TestTagExcludes      []string                     `protobuf:"bytes,5,rep,name=test_tag_excludes,json=testTagExcludes,proto3" json:"test_tag_excludes,omitempty"` // Deprecated: Do not use.
+	Requirements         *SourceTestPlan_Requirements `protobuf:"bytes,13,opt,name=requirements,proto3" json:"requirements,omitempty"`                               // Deprecated: Do not use.
 	XXX_NoUnkeyedLiteral struct{}                     `json:"-"`
 	XXX_unrecognized     []byte                       `json:"-"`
 	XXX_sizecache        int32                        `json:"-"`
@@ -122,6 +116,7 @@
 
 var xxx_messageInfo_SourceTestPlan proto.InternalMessageInfo
 
+// Deprecated: Do not use.
 func (m *SourceTestPlan) GetEnabledTestEnvironments() []SourceTestPlan_TestEnvironment {
 	if m != nil {
 		return m.EnabledTestEnvironments
@@ -143,6 +138,14 @@
 	return nil
 }
 
+func (m *SourceTestPlan) GetTestPlanStarlarkFiles() []*SourceTestPlan_TestPlanStarlarkFile {
+	if m != nil {
+		return m.TestPlanStarlarkFiles
+	}
+	return nil
+}
+
+// Deprecated: Do not use.
 func (m *SourceTestPlan) GetTestTags() []string {
 	if m != nil {
 		return m.TestTags
@@ -150,6 +153,7 @@
 	return nil
 }
 
+// Deprecated: Do not use.
 func (m *SourceTestPlan) GetTestTagExcludes() []string {
 	if m != nil {
 		return m.TestTagExcludes
@@ -157,6 +161,7 @@
 	return nil
 }
 
+// Deprecated: Do not use.
 func (m *SourceTestPlan) GetRequirements() *SourceTestPlan_Requirements {
 	if m != nil {
 		return m.Requirements
@@ -164,6 +169,60 @@
 	return nil
 }
 
+// A Starlark file that will be evaluated to generate HW/VMTestPlan protos.
+//
+// The Starlark file must output a list of HW/VMTestPlan protos based on an
+// input BuildMetadataList and FlatConfigList.
+type SourceTestPlan_TestPlanStarlarkFile struct {
+	// Repo containing the Starlark file.
+	Repo string `protobuf:"bytes,1,opt,name=repo,proto3" json:"repo,omitempty"`
+	// Absolute path within the repo to the Starlark file. Regexes are not
+	// allowed.
+	Path                 string   `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *SourceTestPlan_TestPlanStarlarkFile) Reset()         { *m = SourceTestPlan_TestPlanStarlarkFile{} }
+func (m *SourceTestPlan_TestPlanStarlarkFile) String() string { return proto.CompactTextString(m) }
+func (*SourceTestPlan_TestPlanStarlarkFile) ProtoMessage()    {}
+func (*SourceTestPlan_TestPlanStarlarkFile) Descriptor() ([]byte, []int) {
+	return fileDescriptor_28090e75a41618a0, []int{0, 0}
+}
+
+func (m *SourceTestPlan_TestPlanStarlarkFile) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_SourceTestPlan_TestPlanStarlarkFile.Unmarshal(m, b)
+}
+func (m *SourceTestPlan_TestPlanStarlarkFile) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_SourceTestPlan_TestPlanStarlarkFile.Marshal(b, m, deterministic)
+}
+func (m *SourceTestPlan_TestPlanStarlarkFile) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_SourceTestPlan_TestPlanStarlarkFile.Merge(m, src)
+}
+func (m *SourceTestPlan_TestPlanStarlarkFile) XXX_Size() int {
+	return xxx_messageInfo_SourceTestPlan_TestPlanStarlarkFile.Size(m)
+}
+func (m *SourceTestPlan_TestPlanStarlarkFile) XXX_DiscardUnknown() {
+	xxx_messageInfo_SourceTestPlan_TestPlanStarlarkFile.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_SourceTestPlan_TestPlanStarlarkFile proto.InternalMessageInfo
+
+func (m *SourceTestPlan_TestPlanStarlarkFile) GetRepo() string {
+	if m != nil {
+		return m.Repo
+	}
+	return ""
+}
+
+func (m *SourceTestPlan_TestPlanStarlarkFile) GetPath() string {
+	if m != nil {
+		return m.Path
+	}
+	return ""
+}
+
 // Requirements that must be satisfied by the SourceTestPlan.
 //
 // Each field in the Requirements message should describe a requirement, e.g.
@@ -197,7 +256,7 @@
 func (m *SourceTestPlan_Requirements) String() string { return proto.CompactTextString(m) }
 func (*SourceTestPlan_Requirements) ProtoMessage()    {}
 func (*SourceTestPlan_Requirements) Descriptor() ([]byte, []int) {
-	return fileDescriptor_28090e75a41618a0, []int{0, 0}
+	return fileDescriptor_28090e75a41618a0, []int{0, 1}
 }
 
 func (m *SourceTestPlan_Requirements) XXX_Unmarshal(b []byte) error {
@@ -289,7 +348,7 @@
 }
 func (*SourceTestPlan_Requirements_KernelVersions) ProtoMessage() {}
 func (*SourceTestPlan_Requirements_KernelVersions) Descriptor() ([]byte, []int) {
-	return fileDescriptor_28090e75a41618a0, []int{0, 0, 0}
+	return fileDescriptor_28090e75a41618a0, []int{0, 1, 0}
 }
 
 func (m *SourceTestPlan_Requirements_KernelVersions) XXX_Unmarshal(b []byte) error {
@@ -323,7 +382,7 @@
 func (m *SourceTestPlan_Requirements_SocFamilies) String() string { return proto.CompactTextString(m) }
 func (*SourceTestPlan_Requirements_SocFamilies) ProtoMessage()    {}
 func (*SourceTestPlan_Requirements_SocFamilies) Descriptor() ([]byte, []int) {
-	return fileDescriptor_28090e75a41618a0, []int{0, 0, 1}
+	return fileDescriptor_28090e75a41618a0, []int{0, 1, 1}
 }
 
 func (m *SourceTestPlan_Requirements_SocFamilies) XXX_Unmarshal(b []byte) error {
@@ -357,7 +416,7 @@
 func (m *SourceTestPlan_Requirements_Architectures) String() string { return proto.CompactTextString(m) }
 func (*SourceTestPlan_Requirements_Architectures) ProtoMessage()    {}
 func (*SourceTestPlan_Requirements_Architectures) Descriptor() ([]byte, []int) {
-	return fileDescriptor_28090e75a41618a0, []int{0, 0, 2}
+	return fileDescriptor_28090e75a41618a0, []int{0, 1, 2}
 }
 
 func (m *SourceTestPlan_Requirements_Architectures) XXX_Unmarshal(b []byte) error {
@@ -391,7 +450,7 @@
 func (m *SourceTestPlan_Requirements_ArcVersions) String() string { return proto.CompactTextString(m) }
 func (*SourceTestPlan_Requirements_ArcVersions) ProtoMessage()    {}
 func (*SourceTestPlan_Requirements_ArcVersions) Descriptor() ([]byte, []int) {
-	return fileDescriptor_28090e75a41618a0, []int{0, 0, 3}
+	return fileDescriptor_28090e75a41618a0, []int{0, 1, 3}
 }
 
 func (m *SourceTestPlan_Requirements_ArcVersions) XXX_Unmarshal(b []byte) error {
@@ -425,7 +484,7 @@
 func (m *SourceTestPlan_Requirements_Fingerprint) String() string { return proto.CompactTextString(m) }
 func (*SourceTestPlan_Requirements_Fingerprint) ProtoMessage()    {}
 func (*SourceTestPlan_Requirements_Fingerprint) Descriptor() ([]byte, []int) {
-	return fileDescriptor_28090e75a41618a0, []int{0, 0, 4}
+	return fileDescriptor_28090e75a41618a0, []int{0, 1, 4}
 }
 
 func (m *SourceTestPlan_Requirements_Fingerprint) XXX_Unmarshal(b []byte) error {
@@ -457,7 +516,7 @@
 func (m *SourceTestPlan_Requirements_Parallels) String() string { return proto.CompactTextString(m) }
 func (*SourceTestPlan_Requirements_Parallels) ProtoMessage()    {}
 func (*SourceTestPlan_Requirements_Parallels) Descriptor() ([]byte, []int) {
-	return fileDescriptor_28090e75a41618a0, []int{0, 0, 5}
+	return fileDescriptor_28090e75a41618a0, []int{0, 1, 5}
 }
 
 func (m *SourceTestPlan_Requirements_Parallels) XXX_Unmarshal(b []byte) error {
@@ -493,7 +552,7 @@
 }
 func (*SourceTestPlan_Requirements_ChromeOSConfig) ProtoMessage() {}
 func (*SourceTestPlan_Requirements_ChromeOSConfig) Descriptor() ([]byte, []int) {
-	return fileDescriptor_28090e75a41618a0, []int{0, 0, 6}
+	return fileDescriptor_28090e75a41618a0, []int{0, 1, 6}
 }
 
 func (m *SourceTestPlan_Requirements_ChromeOSConfig) XXX_Unmarshal(b []byte) error {
@@ -537,7 +596,7 @@
 }
 func (*SourceTestPlan_Requirements_FirmwareROVersions) ProtoMessage() {}
 func (*SourceTestPlan_Requirements_FirmwareROVersions) Descriptor() ([]byte, []int) {
-	return fileDescriptor_28090e75a41618a0, []int{0, 0, 7}
+	return fileDescriptor_28090e75a41618a0, []int{0, 1, 7}
 }
 
 func (m *SourceTestPlan_Requirements_FirmwareROVersions) XXX_Unmarshal(b []byte) error {
@@ -568,6 +627,7 @@
 func init() {
 	proto.RegisterEnum("chromiumos.test.plan.SourceTestPlan_TestEnvironment", SourceTestPlan_TestEnvironment_name, SourceTestPlan_TestEnvironment_value)
 	proto.RegisterType((*SourceTestPlan)(nil), "chromiumos.test.plan.SourceTestPlan")
+	proto.RegisterType((*SourceTestPlan_TestPlanStarlarkFile)(nil), "chromiumos.test.plan.SourceTestPlan.TestPlanStarlarkFile")
 	proto.RegisterType((*SourceTestPlan_Requirements)(nil), "chromiumos.test.plan.SourceTestPlan.Requirements")
 	proto.RegisterType((*SourceTestPlan_Requirements_KernelVersions)(nil), "chromiumos.test.plan.SourceTestPlan.Requirements.KernelVersions")
 	proto.RegisterType((*SourceTestPlan_Requirements_SocFamilies)(nil), "chromiumos.test.plan.SourceTestPlan.Requirements.SocFamilies")
@@ -585,49 +645,53 @@
 }
 
 var fileDescriptor_28090e75a41618a0 = []byte{
-	// 692 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x95, 0xdd, 0x6e, 0xd3, 0x3c,
-	0x18, 0xc7, 0xdf, 0xae, 0xeb, 0xd6, 0x3e, 0xe9, 0xd7, 0x6b, 0x55, 0x5a, 0xdf, 0xbc, 0x1c, 0x94,
-	0x1d, 0x4d, 0x20, 0xa5, 0x63, 0x70, 0x80, 0x40, 0x08, 0xca, 0x96, 0x89, 0x02, 0xeb, 0x2a, 0x37,
-	0x1b, 0x02, 0x21, 0x05, 0x2f, 0x73, 0xb3, 0x68, 0x49, 0x1c, 0xec, 0xb4, 0x6c, 0x37, 0xc1, 0x3d,
-	0x70, 0x7f, 0x9c, 0x70, 0x07, 0xc8, 0x4e, 0xdb, 0x24, 0x1b, 0x48, 0xb4, 0xe2, 0x2c, 0xcf, 0x87,
-	0x7f, 0xff, 0xf8, 0xef, 0x47, 0x36, 0xdc, 0x77, 0x2e, 0x38, 0x0b, 0xbc, 0x49, 0xc0, 0x44, 0x37,
-	0xa6, 0x22, 0xee, 0x46, 0x3e, 0x09, 0xbb, 0x82, 0x4d, 0xb8, 0x43, 0x6d, 0x99, 0xb0, 0x65, 0xc2,
-	0x88, 0x38, 0x8b, 0x19, 0x6a, 0xa5, 0xcd, 0x86, 0xac, 0x19, 0xb2, 0xb6, 0xfd, 0xa3, 0x0a, 0xf5,
-	0x91, 0x5a, 0x60, 0x51, 0x11, 0x0f, 0x7d, 0x12, 0xa2, 0x08, 0xfe, 0xa3, 0x21, 0x39, 0xf3, 0xe9,
-	0x79, 0xc2, 0xa0, 0xe1, 0xd4, 0xe3, 0x2c, 0x0c, 0x68, 0x18, 0x8b, 0x76, 0xa1, 0x53, 0xdc, 0xa9,
-	0xef, 0x3d, 0x32, 0x7e, 0x05, 0x33, 0xf2, 0x20, 0x43, 0x7e, 0x98, 0xe9, 0x62, 0xbc, 0x35, 0xc3,
-	0xde, 0xc8, 0x0b, 0x74, 0x17, 0xaa, 0x11, 0x89, 0x2f, 0x6c, 0x4e, 0x5d, 0x7a, 0x15, 0x89, 0xf6,
-	0x5a, 0xa7, 0xb8, 0x53, 0xc1, 0x9a, 0xcc, 0xe1, 0x24, 0x85, 0x76, 0xa1, 0x95, 0x69, 0xb1, 0xe9,
-	0x95, 0xe3, 0x4f, 0xce, 0xa9, 0x68, 0x17, 0x55, 0x2b, 0x4a, 0x5b, 0xcd, 0x59, 0x05, 0xfd, 0x0f,
-	0x15, 0xf5, 0xfb, 0x31, 0x71, 0x45, 0x7b, 0x5d, 0xb5, 0x95, 0x65, 0xc2, 0x22, 0xae, 0x40, 0xf7,
-	0xe0, 0xdf, 0x79, 0x31, 0x65, 0x95, 0x54, 0x53, 0x63, 0xd6, 0xb4, 0x00, 0x9d, 0x40, 0x95, 0xd3,
-	0xcf, 0x13, 0x8f, 0xd3, 0xc4, 0x82, 0x5a, 0xa7, 0xb0, 0xa3, 0xed, 0x3d, 0xf8, 0x23, 0x0b, 0x70,
-	0x66, 0x21, 0xce, 0x61, 0xf4, 0x6f, 0x15, 0xa8, 0x66, 0xcb, 0xc8, 0x83, 0xc6, 0x25, 0xe5, 0x21,
-	0xf5, 0xed, 0x29, 0xe5, 0xc2, 0x63, 0xa1, 0x74, 0x5b, 0x4a, 0xbd, 0x58, 0x5a, 0xca, 0x78, 0xa3,
-	0x40, 0xa7, 0x33, 0x0e, 0xae, 0x5f, 0xe6, 0x62, 0xf4, 0x09, 0xaa, 0x82, 0x39, 0xf6, 0x98, 0x04,
-	0x9e, 0xef, 0x51, 0x69, 0xb8, 0xd4, 0x79, 0xb6, 0xbc, 0xce, 0x88, 0x39, 0x87, 0x33, 0x08, 0xd6,
-	0x44, 0x1a, 0x20, 0x0a, 0x35, 0xc2, 0x9d, 0x0b, 0x2f, 0xa6, 0x4e, 0x3c, 0xe1, 0xea, 0xa0, 0xa4,
-	0xc4, 0xf3, 0xe5, 0x25, 0x7a, 0x59, 0x0c, 0xce, 0x53, 0xe5, 0x46, 0x08, 0x77, 0x52, 0xc3, 0xd6,
-	0x57, 0xdd, 0x48, 0x8f, 0x3b, 0x0b, 0xb7, 0x34, 0x92, 0x06, 0xc8, 0x06, 0x6d, 0xec, 0x85, 0x2e,
-	0xe5, 0x11, 0xf7, 0xc2, 0xb8, 0x5d, 0x5a, 0x55, 0xe0, 0x30, 0x85, 0xe0, 0x2c, 0x11, 0xbd, 0x87,
-	0x4a, 0x44, 0x38, 0xf1, 0x7d, 0xea, 0x8b, 0xf6, 0x86, 0xc2, 0x3f, 0x5d, 0x1e, 0x3f, 0x9c, 0x23,
-	0x70, 0x4a, 0x93, 0x13, 0xa5, 0x40, 0x94, 0x09, 0xdb, 0x61, 0xe1, 0xd8, 0x73, 0xdb, 0x9b, 0xab,
-	0x4e, 0xd4, 0xbe, 0x02, 0x1d, 0x8f, 0xf6, 0x15, 0x07, 0xd7, 0xe7, 0xe0, 0x24, 0x46, 0x53, 0x68,
-	0x8d, 0x3d, 0x1e, 0x7c, 0x21, 0x9c, 0xda, 0x9c, 0xa5, 0x07, 0x52, 0x56, 0x7a, 0x07, 0xab, 0xf8,
-	0x95, 0xd0, 0xf0, 0xf1, 0xe2, 0x5c, 0xd0, 0x5c, 0x01, 0xb3, 0x79, 0x4e, 0x6f, 0x42, 0x3d, 0x3f,
-	0xeb, 0x7a, 0x0d, 0xb4, 0xcc, 0x54, 0xea, 0x0d, 0xa8, 0xe5, 0x26, 0x48, 0xd6, 0x33, 0x87, 0x2d,
-	0xc3, 0xcc, 0xd1, 0xe8, 0x1a, 0x54, 0x16, 0x56, 0x4a, 0x78, 0x7e, 0xdb, 0xfa, 0xf7, 0x02, 0xa0,
-	0xdb, 0x7f, 0x86, 0xbe, 0x16, 0xa0, 0x15, 0x71, 0xe6, 0x72, 0x12, 0xd8, 0x31, 0xb3, 0x03, 0xcf,
-	0xa7, 0x22, 0x66, 0x21, 0x55, 0xd7, 0xa5, 0xb6, 0xf7, 0xf1, 0x6f, 0x6c, 0xdf, 0x18, 0x26, 0x02,
-	0x16, 0x3b, 0x9a, 0xe3, 0xcd, 0x30, 0xe6, 0xd7, 0x18, 0x45, 0xb7, 0x0a, 0xba, 0x09, 0x5b, 0xbf,
-	0x69, 0x47, 0x4d, 0x28, 0x5e, 0xd2, 0x6b, 0x75, 0xb5, 0x54, 0xb0, 0xfc, 0x44, 0x2d, 0x28, 0x4d,
-	0x89, 0x3f, 0xa1, 0xea, 0x1a, 0x28, 0xe1, 0x24, 0x78, 0xb2, 0xf6, 0xb8, 0xb0, 0x3d, 0x80, 0xc6,
-	0x8d, 0xcb, 0x1a, 0x75, 0xe0, 0x8e, 0x65, 0x8e, 0x2c, 0xdb, 0x1c, 0x9c, 0xf6, 0xf1, 0xf1, 0xe0,
-	0xc8, 0x1c, 0x58, 0xf6, 0xc9, 0x60, 0x34, 0x34, 0xf7, 0xfb, 0x87, 0x7d, 0xf3, 0xa0, 0xf9, 0x0f,
-	0xaa, 0x42, 0xf9, 0x55, 0x0f, 0x1f, 0xbc, 0xeb, 0x61, 0xb3, 0x59, 0x40, 0x1a, 0x6c, 0x9e, 0xf6,
-	0xb1, 0x75, 0xd2, 0x7b, 0xdb, 0x5c, 0x7b, 0xbd, 0x5e, 0xde, 0x68, 0xd6, 0x5e, 0xee, 0x7e, 0x30,
-	0x5c, 0xb6, 0xb0, 0xc4, 0x60, 0xdc, 0xed, 0x66, 0x1e, 0xb2, 0x64, 0x50, 0xbb, 0x2e, 0x4b, 0x9f,
-	0xb4, 0xb3, 0x0d, 0xf5, 0x84, 0x3d, 0xfc, 0x19, 0x00, 0x00, 0xff, 0xff, 0x28, 0xac, 0x5e, 0x90,
-	0xf1, 0x06, 0x00, 0x00,
+	// 764 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x95, 0xdb, 0x6e, 0xdb, 0x36,
+	0x18, 0x80, 0x27, 0x1f, 0x12, 0x9b, 0xf2, 0x69, 0x84, 0x87, 0x68, 0xc2, 0x80, 0x79, 0xb9, 0x32,
+	0x30, 0x40, 0xce, 0xbc, 0x5d, 0xec, 0x80, 0xb5, 0x75, 0x12, 0x19, 0x75, 0xdb, 0x38, 0x06, 0xed,
+	0xa4, 0x48, 0x51, 0x40, 0x65, 0x14, 0x5a, 0x11, 0x2c, 0x8b, 0x2a, 0x49, 0xbb, 0xc9, 0x4b, 0xf4,
+	0x1d, 0xfa, 0x10, 0x7d, 0xab, 0x3e, 0x44, 0x41, 0xca, 0xb6, 0xe4, 0x24, 0x05, 0x62, 0xa3, 0x77,
+	0xfc, 0x0f, 0xfc, 0xfe, 0x23, 0x48, 0xf0, 0xbb, 0x7b, 0xcd, 0xe8, 0xd4, 0x9f, 0x4d, 0x29, 0x6f,
+	0x09, 0xc2, 0x45, 0x2b, 0x0a, 0x70, 0xd8, 0xe2, 0x74, 0xc6, 0x5c, 0xe2, 0x48, 0x85, 0x23, 0x15,
+	0x56, 0xc4, 0xa8, 0xa0, 0xb0, 0x9e, 0x38, 0x5b, 0xd2, 0x66, 0x49, 0xdb, 0xfe, 0xe7, 0x0a, 0xa8,
+	0x0c, 0xd5, 0x85, 0x11, 0xe1, 0x62, 0x10, 0xe0, 0x10, 0x0a, 0xf0, 0x33, 0x09, 0xf1, 0x65, 0x40,
+	0xae, 0x62, 0x06, 0x09, 0xe7, 0x3e, 0xa3, 0xe1, 0x94, 0x84, 0x82, 0x1b, 0x5a, 0x23, 0xdb, 0xac,
+	0xb4, 0xff, 0xb2, 0x1e, 0x82, 0x59, 0xeb, 0x20, 0x4b, 0x1e, 0xec, 0xe4, 0xf2, 0x61, 0xc6, 0xd0,
+	0xd0, 0xde, 0x02, 0x7d, 0xc7, 0xc6, 0xe1, 0x6f, 0xa0, 0x14, 0x61, 0x71, 0xed, 0x30, 0xe2, 0x91,
+	0x9b, 0x88, 0x1b, 0x99, 0x46, 0xb6, 0x59, 0x44, 0xba, 0xd4, 0xa1, 0x58, 0x05, 0x0f, 0x40, 0x3d,
+	0xe5, 0xe2, 0x90, 0x1b, 0x37, 0x98, 0x5d, 0x11, 0x6e, 0x64, 0x95, 0x2b, 0x4c, 0x5c, 0xed, 0x85,
+	0x05, 0x32, 0x60, 0xac, 0xda, 0xe0, 0x70, 0x81, 0x59, 0x80, 0xd9, 0xc4, 0x19, 0xfb, 0x01, 0xe1,
+	0x46, 0xb5, 0x91, 0x6d, 0xea, 0xed, 0x7f, 0x1e, 0x5d, 0x89, 0x3c, 0x0c, 0x17, 0x88, 0xae, 0x1f,
+	0x10, 0xf4, 0x93, 0x78, 0x40, 0xcb, 0xe1, 0xaf, 0xa0, 0xa8, 0x62, 0x0a, 0xec, 0x71, 0x23, 0x27,
+	0x53, 0x53, 0x85, 0x17, 0xa4, 0x72, 0x84, 0x3d, 0x0e, 0x2d, 0xf0, 0xe3, 0xd2, 0x21, 0xa9, 0x21,
+	0xbf, 0x72, 0xac, 0x2e, 0x1c, 0x57, 0x45, 0x5c, 0x80, 0x12, 0x23, 0xef, 0x67, 0x3e, 0x23, 0xf1,
+	0x08, 0xca, 0x0d, 0xad, 0xa9, 0xb7, 0xff, 0x78, 0x54, 0xe2, 0x28, 0x75, 0x51, 0xd1, 0xd7, 0x50,
+	0xe6, 0x13, 0x50, 0x7f, 0xa8, 0x34, 0x08, 0x41, 0x8e, 0x91, 0x88, 0x1a, 0x5a, 0x43, 0x6b, 0x16,
+	0x91, 0x3a, 0x4b, 0x9d, 0xec, 0xb0, 0x91, 0x89, 0x75, 0xf2, 0x6c, 0x7e, 0x2a, 0x82, 0x52, 0x3a,
+	0x04, 0xf4, 0x41, 0x75, 0x42, 0x58, 0x48, 0x02, 0x67, 0x4e, 0x18, 0xf7, 0x69, 0xc8, 0x15, 0x43,
+	0x6f, 0x3f, 0xdb, 0x38, 0x5d, 0xeb, 0xa5, 0x02, 0x9d, 0x2f, 0x38, 0xa8, 0x32, 0x59, 0x93, 0xe1,
+	0x3b, 0x50, 0xe2, 0xd4, 0x75, 0xc6, 0x78, 0xea, 0x07, 0x3e, 0xe1, 0x2a, 0x2f, 0xbd, 0xfd, 0xff,
+	0xe6, 0x71, 0x86, 0xd4, 0xed, 0x2e, 0x20, 0x48, 0xe7, 0x89, 0x00, 0x09, 0x28, 0x63, 0xe6, 0x5e,
+	0xfb, 0x82, 0xb8, 0x62, 0xc6, 0xd4, 0xa2, 0xc9, 0x10, 0x4f, 0x37, 0x0f, 0xd1, 0x49, 0x63, 0xd0,
+	0x3a, 0x55, 0x16, 0x82, 0x99, 0x9b, 0x34, 0x2c, 0xb7, 0x6d, 0x21, 0x1d, 0xe6, 0xae, 0xba, 0xa5,
+	0xe3, 0x44, 0x80, 0x0e, 0xd0, 0xc7, 0x7e, 0xe8, 0x11, 0x16, 0x31, 0x3f, 0x14, 0x46, 0x7e, 0xdb,
+	0x00, 0xdd, 0x04, 0x82, 0xd2, 0x44, 0x78, 0x01, 0x8a, 0x11, 0x66, 0x38, 0x08, 0x48, 0xc0, 0x8d,
+	0x1d, 0x85, 0xff, 0x6f, 0x73, 0xfc, 0x60, 0x89, 0x40, 0x09, 0x4d, 0x6e, 0x94, 0x02, 0x11, 0xca,
+	0x1d, 0x97, 0x86, 0x63, 0xdf, 0x33, 0x76, 0xb7, 0xdd, 0xa8, 0x23, 0x05, 0x3a, 0x1d, 0x1e, 0x29,
+	0x0e, 0xaa, 0x2c, 0xc1, 0xb1, 0x0c, 0xe7, 0xa0, 0x3e, 0xf6, 0xd9, 0xf4, 0x03, 0x66, 0xc4, 0x61,
+	0x34, 0x19, 0x48, 0x41, 0xc5, 0x3b, 0xde, 0xa6, 0x5f, 0x31, 0x0d, 0x9d, 0xae, 0xe6, 0x02, 0x97,
+	0x11, 0x10, 0x5d, 0xea, 0xcc, 0x1a, 0xa8, 0xac, 0xef, 0xba, 0x59, 0x06, 0x7a, 0x6a, 0x2b, 0xcd,
+	0x2a, 0x28, 0xaf, 0x6d, 0x90, 0xb4, 0xa7, 0x86, 0x2d, 0xc5, 0xd4, 0x68, 0x4c, 0x1d, 0x14, 0x57,
+	0xad, 0x94, 0xf0, 0xf5, 0xb2, 0xcd, 0x2f, 0x1a, 0x80, 0xf7, 0x33, 0x83, 0x1f, 0x35, 0x50, 0x8f,
+	0x18, 0xf5, 0x18, 0x9e, 0x3a, 0x82, 0x3a, 0x53, 0xf9, 0x98, 0x09, 0x1a, 0x12, 0xf5, 0xe4, 0xeb,
+	0xed, 0xb7, 0xdf, 0xa3, 0x7c, 0x6b, 0x10, 0x07, 0x18, 0xd1, 0x93, 0x25, 0xde, 0x0e, 0x05, 0xbb,
+	0x45, 0x30, 0xba, 0x67, 0x30, 0x6d, 0xb0, 0xf7, 0x0d, 0x77, 0x58, 0x03, 0xd9, 0x09, 0xb9, 0x5d,
+	0x3c, 0x4f, 0xf2, 0x08, 0xeb, 0x20, 0x3f, 0xc7, 0xc1, 0x8c, 0xa8, 0x67, 0x20, 0x8f, 0x62, 0xe1,
+	0xdf, 0xcc, 0xdf, 0xda, 0x7e, 0x1f, 0x54, 0xef, 0x7c, 0x36, 0xb0, 0x01, 0x7e, 0x19, 0xd9, 0xc3,
+	0x91, 0x63, 0xf7, 0xcf, 0x7b, 0xe8, 0xb4, 0x7f, 0x62, 0xf7, 0x47, 0xce, 0x59, 0x7f, 0x38, 0xb0,
+	0x8f, 0x7a, 0xdd, 0x9e, 0x7d, 0x5c, 0xfb, 0x01, 0x96, 0x40, 0xe1, 0x79, 0x07, 0x1d, 0xbf, 0xee,
+	0x20, 0xbb, 0xa6, 0x41, 0x1d, 0xec, 0x9e, 0xf7, 0xd0, 0xe8, 0xac, 0xf3, 0xaa, 0x96, 0x79, 0x91,
+	0x2b, 0xec, 0xd4, 0xca, 0x87, 0x07, 0x6f, 0x2c, 0x8f, 0xae, 0x5a, 0x62, 0x51, 0xe6, 0xb5, 0x52,
+	0x9f, 0x71, 0xbc, 0xa8, 0x2d, 0x8f, 0x26, 0xdf, 0xf2, 0xe5, 0x8e, 0xfa, 0x86, 0xff, 0xfc, 0x1a,
+	0x00, 0x00, 0xff, 0xff, 0x82, 0xbf, 0x9c, 0x9c, 0xb5, 0x07, 0x00, 0x00,
 }
diff --git a/proto/chromiumos/test/plan/source_test_plan.proto b/proto/chromiumos/test/plan/source_test_plan.proto
index 93079ff..c05cc7b 100644
--- a/proto/chromiumos/test/plan/source_test_plan.proto
+++ b/proto/chromiumos/test/plan/source_test_plan.proto
@@ -8,19 +8,13 @@
 
 option go_package = "go.chromium.org/chromiumos/config/go/test/plan";
 
-// Describes the test cases, software requirements, and hardware requirements
-// that run when a given set of files are changed.
-//
-// This message contains high-level rules for test planning, e.g. "test on all
-// kernel versions". This is then evaluated into a Specification message which
-// contains attributes that must be tested; in the above example, this would be
-// a list of kernel versions used by ChromeOS.
+// Describes the test cases that run when a given set of files are changed.
 //
 // This message is intended to be specified as text proto in a DIR_METADATA file
 // in the source tree, and should be concise enough Starlark, or another config
 // generation tool, is not needed.
 //
-// NEXT ID: 14
+// NEXT ID: 15
 message SourceTestPlan {
   // Different environments ChromeOS tests run in.
   enum TestEnvironment {
@@ -28,10 +22,7 @@
     HARDWARE = 1;
     VIRTUAL = 2;
   }
-
-  // Test environments enabled for the test plan. Must contain at least one
-  // test type.
-  repeated TestEnvironment enabled_test_environments = 1;
+  repeated TestEnvironment enabled_test_environments = 1 [deprecated = true];
 
   // Paths that will trigger the SourceTestPlan.
   //
@@ -53,12 +44,28 @@
   repeated string path_regexps = 2;
   repeated string path_regexp_excludes = 3;
 
+  // A Starlark file that will be evaluated to generate HW/VMTestPlan protos.
+  //
+  // The Starlark file must output a list of HW/VMTestPlan protos based on an
+  // input BuildMetadataList and FlatConfigList.
+  message TestPlanStarlarkFile {
+    // Repo containing the Starlark file.
+    string repo = 1;
+
+    // Absolute path within the repo to the Starlark file. Regexes are not
+    // allowed.
+    string path = 2;
+  }
+
+  // Starlark files to evaluate to generate HW/VMTestPlan protos.
+  repeated TestPlanStarlarkFile test_plan_starlark_files = 15;
+
   // Only run tests that have at least one of test_tags (if specified) and do
   // not have any of test_tag_excludes.
   //
   // Tags must match exactly (i.e. no regexp, wildcard, etc. allowed).
-  repeated string test_tags = 4;
-  repeated string test_tag_excludes = 5;
+  repeated string test_tags = 4 [deprecated = true];
+  repeated string test_tag_excludes = 5 [deprecated = true];
 
   // Requirements that must be satisfied by the SourceTestPlan.
   //
@@ -119,7 +126,7 @@
     FirmwareROVersions firmware_ro_versions = 8;
   }
 
-  Requirements requirements = 13;
+  Requirements requirements = 13 [deprecated = true];
 
   reserved 6 to 12;
 }
diff --git a/python/chromiumos/test/plan/source_test_plan_pb2.py b/python/chromiumos/test/plan/source_test_plan_pb2.py
index cae7828..d454a21 100644
--- a/python/chromiumos/test/plan/source_test_plan_pb2.py
+++ b/python/chromiumos/test/plan/source_test_plan_pb2.py
@@ -19,7 +19,7 @@
   package='chromiumos.test.plan',
   syntax='proto3',
   serialized_options=_b('Z.go.chromium.org/chromiumos/config/go/test/plan'),
-  serialized_pb=_b('\n+chromiumos/test/plan/source_test_plan.proto\x12\x14\x63hromiumos.test.plan\"\xf8\n\n\x0eSourceTestPlan\x12W\n\x19\x65nabled_test_environments\x18\x01 \x03(\x0e\x32\x34.chromiumos.test.plan.SourceTestPlan.TestEnvironment\x12\x14\n\x0cpath_regexps\x18\x02 \x03(\t\x12\x1c\n\x14path_regexp_excludes\x18\x03 \x03(\t\x12\x11\n\ttest_tags\x18\x04 \x03(\t\x12\x19\n\x11test_tag_excludes\x18\x05 \x03(\t\x12G\n\x0crequirements\x18\r \x01(\x0b\x32\x31.chromiumos.test.plan.SourceTestPlan.Requirements\x1a\x8b\x08\n\x0cRequirements\x12Y\n\x0fkernel_versions\x18\x01 \x01(\x0b\x32@.chromiumos.test.plan.SourceTestPlan.Requirements.KernelVersions\x12S\n\x0csoc_families\x18\x02 \x01(\x0b\x32=.chromiumos.test.plan.SourceTestPlan.Requirements.SocFamilies\x12V\n\rarchitectures\x18\x03 \x01(\x0b\x32?.chromiumos.test.plan.SourceTestPlan.Requirements.Architectures\x12S\n\x0c\x61rc_versions\x18\x04 \x01(\x0b\x32=.chromiumos.test.plan.SourceTestPlan.Requirements.ArcVersions\x12R\n\x0b\x66ingerprint\x18\x05 \x01(\x0b\x32=.chromiumos.test.plan.SourceTestPlan.Requirements.Fingerprint\x12N\n\tparallels\x18\x06 \x01(\x0b\x32;.chromiumos.test.plan.SourceTestPlan.Requirements.Parallels\x12Y\n\x0f\x63hromeos_config\x18\x07 \x01(\x0b\x32@.chromiumos.test.plan.SourceTestPlan.Requirements.ChromeOSConfig\x12\x62\n\x14\x66irmware_ro_versions\x18\x08 \x01(\x0b\x32\x44.chromiumos.test.plan.SourceTestPlan.Requirements.FirmwareROVersions\x1a\x10\n\x0eKernelVersions\x1a\r\n\x0bSocFamilies\x1a\x0f\n\rArchitectures\x1a\r\n\x0b\x41rcVersions\x1a\r\n\x0b\x46ingerprint\x1a\x0b\n\tParallels\x1a\x10\n\x0e\x43hromeOSConfig\x1a\xcb\x01\n\x12\x46irmwareROVersions\x12z\n\x14program_to_milestone\x18\x01 \x03(\x0b\x32\\.chromiumos.test.plan.SourceTestPlan.Requirements.FirmwareROVersions.ProgramToMilestoneEntry\x1a\x39\n\x17ProgramToMilestoneEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\"N\n\x0fTestEnvironment\x12 \n\x1cTEST_ENVIRONMENT_UNSPECIFIED\x10\x00\x12\x0c\n\x08HARDWARE\x10\x01\x12\x0b\n\x07VIRTUAL\x10\x02J\x04\x08\x06\x10\rB0Z.go.chromium.org/chromiumos/config/go/test/planb\x06proto3')
+  serialized_pb=_b('\n+chromiumos/test/plan/source_test_plan.proto\x12\x14\x63hromiumos.test.plan\"\x99\x0c\n\x0eSourceTestPlan\x12[\n\x19\x65nabled_test_environments\x18\x01 \x03(\x0e\x32\x34.chromiumos.test.plan.SourceTestPlan.TestEnvironmentB\x02\x18\x01\x12\x14\n\x0cpath_regexps\x18\x02 \x03(\t\x12\x1c\n\x14path_regexp_excludes\x18\x03 \x03(\t\x12[\n\x18test_plan_starlark_files\x18\x0f \x03(\x0b\x32\x39.chromiumos.test.plan.SourceTestPlan.TestPlanStarlarkFile\x12\x15\n\ttest_tags\x18\x04 \x03(\tB\x02\x18\x01\x12\x1d\n\x11test_tag_excludes\x18\x05 \x03(\tB\x02\x18\x01\x12K\n\x0crequirements\x18\r \x01(\x0b\x32\x31.chromiumos.test.plan.SourceTestPlan.RequirementsB\x02\x18\x01\x1a\x32\n\x14TestPlanStarlarkFile\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\x0c\n\x04path\x18\x02 \x01(\t\x1a\x8b\x08\n\x0cRequirements\x12Y\n\x0fkernel_versions\x18\x01 \x01(\x0b\x32@.chromiumos.test.plan.SourceTestPlan.Requirements.KernelVersions\x12S\n\x0csoc_families\x18\x02 \x01(\x0b\x32=.chromiumos.test.plan.SourceTestPlan.Requirements.SocFamilies\x12V\n\rarchitectures\x18\x03 \x01(\x0b\x32?.chromiumos.test.plan.SourceTestPlan.Requirements.Architectures\x12S\n\x0c\x61rc_versions\x18\x04 \x01(\x0b\x32=.chromiumos.test.plan.SourceTestPlan.Requirements.ArcVersions\x12R\n\x0b\x66ingerprint\x18\x05 \x01(\x0b\x32=.chromiumos.test.plan.SourceTestPlan.Requirements.Fingerprint\x12N\n\tparallels\x18\x06 \x01(\x0b\x32;.chromiumos.test.plan.SourceTestPlan.Requirements.Parallels\x12Y\n\x0f\x63hromeos_config\x18\x07 \x01(\x0b\x32@.chromiumos.test.plan.SourceTestPlan.Requirements.ChromeOSConfig\x12\x62\n\x14\x66irmware_ro_versions\x18\x08 \x01(\x0b\x32\x44.chromiumos.test.plan.SourceTestPlan.Requirements.FirmwareROVersions\x1a\x10\n\x0eKernelVersions\x1a\r\n\x0bSocFamilies\x1a\x0f\n\rArchitectures\x1a\r\n\x0b\x41rcVersions\x1a\r\n\x0b\x46ingerprint\x1a\x0b\n\tParallels\x1a\x10\n\x0e\x43hromeOSConfig\x1a\xcb\x01\n\x12\x46irmwareROVersions\x12z\n\x14program_to_milestone\x18\x01 \x03(\x0b\x32\\.chromiumos.test.plan.SourceTestPlan.Requirements.FirmwareROVersions.ProgramToMilestoneEntry\x1a\x39\n\x17ProgramToMilestoneEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x05:\x02\x38\x01\"N\n\x0fTestEnvironment\x12 \n\x1cTEST_ENVIRONMENT_UNSPECIFIED\x10\x00\x12\x0c\n\x08HARDWARE\x10\x01\x12\x0b\n\x07VIRTUAL\x10\x02J\x04\x08\x06\x10\rB0Z.go.chromium.org/chromiumos/config/go/test/planb\x06proto3')
 )
 
 
@@ -45,12 +45,49 @@
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=1386,
-  serialized_end=1464,
+  serialized_start=1547,
+  serialized_end=1625,
 )
 _sym_db.RegisterEnumDescriptor(_SOURCETESTPLAN_TESTENVIRONMENT)
 
 
+_SOURCETESTPLAN_TESTPLANSTARLARKFILE = _descriptor.Descriptor(
+  name='TestPlanStarlarkFile',
+  full_name='chromiumos.test.plan.SourceTestPlan.TestPlanStarlarkFile',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='repo', full_name='chromiumos.test.plan.SourceTestPlan.TestPlanStarlarkFile.repo', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='path', full_name='chromiumos.test.plan.SourceTestPlan.TestPlanStarlarkFile.path', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=457,
+  serialized_end=507,
+)
+
 _SOURCETESTPLAN_REQUIREMENTS_KERNELVERSIONS = _descriptor.Descriptor(
   name='KernelVersions',
   full_name='chromiumos.test.plan.SourceTestPlan.Requirements.KernelVersions',
@@ -70,8 +107,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1069,
-  serialized_end=1085,
+  serialized_start=1230,
+  serialized_end=1246,
 )
 
 _SOURCETESTPLAN_REQUIREMENTS_SOCFAMILIES = _descriptor.Descriptor(
@@ -93,8 +130,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1087,
-  serialized_end=1100,
+  serialized_start=1248,
+  serialized_end=1261,
 )
 
 _SOURCETESTPLAN_REQUIREMENTS_ARCHITECTURES = _descriptor.Descriptor(
@@ -116,8 +153,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1102,
-  serialized_end=1117,
+  serialized_start=1263,
+  serialized_end=1278,
 )
 
 _SOURCETESTPLAN_REQUIREMENTS_ARCVERSIONS = _descriptor.Descriptor(
@@ -139,8 +176,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1119,
-  serialized_end=1132,
+  serialized_start=1280,
+  serialized_end=1293,
 )
 
 _SOURCETESTPLAN_REQUIREMENTS_FINGERPRINT = _descriptor.Descriptor(
@@ -162,8 +199,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1134,
-  serialized_end=1147,
+  serialized_start=1295,
+  serialized_end=1308,
 )
 
 _SOURCETESTPLAN_REQUIREMENTS_PARALLELS = _descriptor.Descriptor(
@@ -185,8 +222,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1149,
-  serialized_end=1160,
+  serialized_start=1310,
+  serialized_end=1321,
 )
 
 _SOURCETESTPLAN_REQUIREMENTS_CHROMEOSCONFIG = _descriptor.Descriptor(
@@ -208,8 +245,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1162,
-  serialized_end=1178,
+  serialized_start=1323,
+  serialized_end=1339,
 )
 
 _SOURCETESTPLAN_REQUIREMENTS_FIRMWAREROVERSIONS_PROGRAMTOMILESTONEENTRY = _descriptor.Descriptor(
@@ -245,8 +282,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1327,
-  serialized_end=1384,
+  serialized_start=1488,
+  serialized_end=1545,
 )
 
 _SOURCETESTPLAN_REQUIREMENTS_FIRMWAREROVERSIONS = _descriptor.Descriptor(
@@ -275,8 +312,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1181,
-  serialized_end=1384,
+  serialized_start=1342,
+  serialized_end=1545,
 )
 
 _SOURCETESTPLAN_REQUIREMENTS = _descriptor.Descriptor(
@@ -354,8 +391,8 @@
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=349,
-  serialized_end=1384,
+  serialized_start=510,
+  serialized_end=1545,
 )
 
 _SOURCETESTPLAN = _descriptor.Descriptor(
@@ -371,7 +408,7 @@
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR),
+      serialized_options=_b('\030\001'), file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
       name='path_regexps', full_name='chromiumos.test.plan.SourceTestPlan.path_regexps', index=1,
       number=2, type=9, cpp_type=9, label=3,
@@ -387,30 +424,37 @@
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='test_tags', full_name='chromiumos.test.plan.SourceTestPlan.test_tags', index=3,
+      name='test_plan_starlark_files', full_name='chromiumos.test.plan.SourceTestPlan.test_plan_starlark_files', index=3,
+      number=15, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR),
+    _descriptor.FieldDescriptor(
+      name='test_tags', full_name='chromiumos.test.plan.SourceTestPlan.test_tags', index=4,
       number=4, type=9, cpp_type=9, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR),
+      serialized_options=_b('\030\001'), file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='test_tag_excludes', full_name='chromiumos.test.plan.SourceTestPlan.test_tag_excludes', index=4,
+      name='test_tag_excludes', full_name='chromiumos.test.plan.SourceTestPlan.test_tag_excludes', index=5,
       number=5, type=9, cpp_type=9, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR),
+      serialized_options=_b('\030\001'), file=DESCRIPTOR),
     _descriptor.FieldDescriptor(
-      name='requirements', full_name='chromiumos.test.plan.SourceTestPlan.requirements', index=5,
+      name='requirements', full_name='chromiumos.test.plan.SourceTestPlan.requirements', index=6,
       number=13, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR),
+      serialized_options=_b('\030\001'), file=DESCRIPTOR),
   ],
   extensions=[
   ],
-  nested_types=[_SOURCETESTPLAN_REQUIREMENTS, ],
+  nested_types=[_SOURCETESTPLAN_TESTPLANSTARLARKFILE, _SOURCETESTPLAN_REQUIREMENTS, ],
   enum_types=[
     _SOURCETESTPLAN_TESTENVIRONMENT,
   ],
@@ -421,9 +465,10 @@
   oneofs=[
   ],
   serialized_start=70,
-  serialized_end=1470,
+  serialized_end=1631,
 )
 
+_SOURCETESTPLAN_TESTPLANSTARLARKFILE.containing_type = _SOURCETESTPLAN
 _SOURCETESTPLAN_REQUIREMENTS_KERNELVERSIONS.containing_type = _SOURCETESTPLAN_REQUIREMENTS
 _SOURCETESTPLAN_REQUIREMENTS_SOCFAMILIES.containing_type = _SOURCETESTPLAN_REQUIREMENTS
 _SOURCETESTPLAN_REQUIREMENTS_ARCHITECTURES.containing_type = _SOURCETESTPLAN_REQUIREMENTS
@@ -444,6 +489,7 @@
 _SOURCETESTPLAN_REQUIREMENTS.fields_by_name['firmware_ro_versions'].message_type = _SOURCETESTPLAN_REQUIREMENTS_FIRMWAREROVERSIONS
 _SOURCETESTPLAN_REQUIREMENTS.containing_type = _SOURCETESTPLAN
 _SOURCETESTPLAN.fields_by_name['enabled_test_environments'].enum_type = _SOURCETESTPLAN_TESTENVIRONMENT
+_SOURCETESTPLAN.fields_by_name['test_plan_starlark_files'].message_type = _SOURCETESTPLAN_TESTPLANSTARLARKFILE
 _SOURCETESTPLAN.fields_by_name['requirements'].message_type = _SOURCETESTPLAN_REQUIREMENTS
 _SOURCETESTPLAN_TESTENVIRONMENT.containing_type = _SOURCETESTPLAN
 DESCRIPTOR.message_types_by_name['SourceTestPlan'] = _SOURCETESTPLAN
@@ -451,6 +497,13 @@
 
 SourceTestPlan = _reflection.GeneratedProtocolMessageType('SourceTestPlan', (_message.Message,), dict(
 
+  TestPlanStarlarkFile = _reflection.GeneratedProtocolMessageType('TestPlanStarlarkFile', (_message.Message,), dict(
+    DESCRIPTOR = _SOURCETESTPLAN_TESTPLANSTARLARKFILE,
+    __module__ = 'chromiumos.test.plan.source_test_plan_pb2'
+    # @@protoc_insertion_point(class_scope:chromiumos.test.plan.SourceTestPlan.TestPlanStarlarkFile)
+    ))
+  ,
+
   Requirements = _reflection.GeneratedProtocolMessageType('Requirements', (_message.Message,), dict(
 
     KernelVersions = _reflection.GeneratedProtocolMessageType('KernelVersions', (_message.Message,), dict(
@@ -525,6 +578,7 @@
   # @@protoc_insertion_point(class_scope:chromiumos.test.plan.SourceTestPlan)
   ))
 _sym_db.RegisterMessage(SourceTestPlan)
+_sym_db.RegisterMessage(SourceTestPlan.TestPlanStarlarkFile)
 _sym_db.RegisterMessage(SourceTestPlan.Requirements)
 _sym_db.RegisterMessage(SourceTestPlan.Requirements.KernelVersions)
 _sym_db.RegisterMessage(SourceTestPlan.Requirements.SocFamilies)
@@ -539,4 +593,8 @@
 
 DESCRIPTOR._options = None
 _SOURCETESTPLAN_REQUIREMENTS_FIRMWAREROVERSIONS_PROGRAMTOMILESTONEENTRY._options = None
+_SOURCETESTPLAN.fields_by_name['enabled_test_environments']._options = None
+_SOURCETESTPLAN.fields_by_name['test_tags']._options = None
+_SOURCETESTPLAN.fields_by_name['test_tag_excludes']._options = None
+_SOURCETESTPLAN.fields_by_name['requirements']._options = None
 # @@protoc_insertion_point(module_scope)