1// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 2 3package parser2v1 4 5import ( 6 "fmt" 7 8 "github.com/spdx/tools-golang/spdx/common" 9 "github.com/spdx/tools-golang/spdx/v2_1" 10) 11 12func (parser *tvParser2_1) parsePairFromFile2_1(tag string, value string) error { 13 // expire fileAOP for anything other than an AOPHomePage or AOPURI 14 // (we'll actually handle the HomePage and URI further below) 15 if tag != "ArtifactOfProjectHomePage" && tag != "ArtifactOfProjectURI" { 16 parser.fileAOP = nil 17 } 18 19 switch tag { 20 // tag for creating new file section 21 case "FileName": 22 // check if the previous file contained a spdxId or not 23 if parser.file != nil && parser.file.FileSPDXIdentifier == nullSpdxElementId2_1 { 24 return fmt.Errorf("file with FileName %s does not have SPDX identifier", parser.file.FileName) 25 } 26 parser.file = &v2_1.File{} 27 parser.file.FileName = value 28 // tag for creating new package section and going back to parsing Package 29 case "PackageName": 30 // check if the previous file contained a spdxId or not 31 if parser.file != nil && parser.file.FileSPDXIdentifier == nullSpdxElementId2_1 { 32 return fmt.Errorf("file with FileName %s does not have SPDX identifier", parser.file.FileName) 33 } 34 parser.st = psPackage2_1 35 parser.file = nil 36 return parser.parsePairFromPackage2_1(tag, value) 37 // tag for going on to snippet section 38 case "SnippetSPDXID": 39 parser.st = psSnippet2_1 40 return parser.parsePairFromSnippet2_1(tag, value) 41 // tag for going on to other license section 42 case "LicenseID": 43 parser.st = psOtherLicense2_1 44 return parser.parsePairFromOtherLicense2_1(tag, value) 45 // tags for file data 46 case "SPDXID": 47 eID, err := extractElementID(value) 48 if err != nil { 49 return err 50 } 51 parser.file.FileSPDXIdentifier = eID 52 if parser.pkg == nil { 53 if parser.doc.Files == nil { 54 parser.doc.Files = []*v2_1.File{} 55 } 56 parser.doc.Files = append(parser.doc.Files, parser.file) 57 } else { 58 if parser.pkg.Files == nil { 59 parser.pkg.Files = []*v2_1.File{} 60 } 61 parser.pkg.Files = append(parser.pkg.Files, parser.file) 62 } 63 case "FileType": 64 parser.file.FileTypes = append(parser.file.FileTypes, value) 65 case "FileChecksum": 66 subkey, subvalue, err := extractSubs(value) 67 if err != nil { 68 return err 69 } 70 if parser.file.Checksums == nil { 71 parser.file.Checksums = []common.Checksum{} 72 } 73 switch common.ChecksumAlgorithm(subkey) { 74 case common.SHA1, common.SHA256, common.MD5: 75 algorithm := common.ChecksumAlgorithm(subkey) 76 parser.file.Checksums = append(parser.file.Checksums, common.Checksum{Algorithm: algorithm, Value: subvalue}) 77 default: 78 return fmt.Errorf("got unknown checksum type %s", subkey) 79 } 80 case "LicenseConcluded": 81 parser.file.LicenseConcluded = value 82 case "LicenseInfoInFile": 83 parser.file.LicenseInfoInFiles = append(parser.file.LicenseInfoInFiles, value) 84 case "LicenseComments": 85 parser.file.LicenseComments = value 86 case "FileCopyrightText": 87 parser.file.FileCopyrightText = value 88 case "ArtifactOfProjectName": 89 parser.fileAOP = &v2_1.ArtifactOfProject{} 90 parser.file.ArtifactOfProjects = append(parser.file.ArtifactOfProjects, parser.fileAOP) 91 parser.fileAOP.Name = value 92 case "ArtifactOfProjectHomePage": 93 if parser.fileAOP == nil { 94 return fmt.Errorf("no current ArtifactOfProject found") 95 } 96 parser.fileAOP.HomePage = value 97 case "ArtifactOfProjectURI": 98 if parser.fileAOP == nil { 99 return fmt.Errorf("no current ArtifactOfProject found") 100 } 101 parser.fileAOP.URI = value 102 case "FileComment": 103 parser.file.FileComment = value 104 case "FileNotice": 105 parser.file.FileNotice = value 106 case "FileContributor": 107 parser.file.FileContributors = append(parser.file.FileContributors, value) 108 case "FileDependency": 109 parser.file.FileDependencies = append(parser.file.FileDependencies, value) 110 // for relationship tags, pass along but don't change state 111 case "Relationship": 112 parser.rln = &v2_1.Relationship{} 113 parser.doc.Relationships = append(parser.doc.Relationships, parser.rln) 114 return parser.parsePairForRelationship2_1(tag, value) 115 case "RelationshipComment": 116 return parser.parsePairForRelationship2_1(tag, value) 117 // for annotation tags, pass along but don't change state 118 case "Annotator": 119 parser.ann = &v2_1.Annotation{} 120 parser.doc.Annotations = append(parser.doc.Annotations, parser.ann) 121 return parser.parsePairForAnnotation2_1(tag, value) 122 case "AnnotationDate": 123 return parser.parsePairForAnnotation2_1(tag, value) 124 case "AnnotationType": 125 return parser.parsePairForAnnotation2_1(tag, value) 126 case "SPDXREF": 127 return parser.parsePairForAnnotation2_1(tag, value) 128 case "AnnotationComment": 129 return parser.parsePairForAnnotation2_1(tag, value) 130 // tag for going on to review section (DEPRECATED) 131 case "Reviewer": 132 parser.st = psReview2_1 133 return parser.parsePairFromReview2_1(tag, value) 134 default: 135 return fmt.Errorf("received unknown tag %v in File section", tag) 136 } 137 138 return nil 139} 140