101 lines
3.2 KiB
Go
101 lines
3.2 KiB
Go
// Package parser2v2 contains functions to read, load and parse
|
|
// SPDX tag-value files, version 2.2.
|
|
// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
|
|
package parser2v2
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/spdx/tools-golang/spdx/common"
|
|
"github.com/spdx/tools-golang/spdx/v2_2"
|
|
"github.com/spdx/tools-golang/tvloader/reader"
|
|
)
|
|
|
|
// ParseTagValues takes a list of (tag, value) pairs, parses it and returns
|
|
// a pointer to a parsed SPDX Document.
|
|
func ParseTagValues(tvs []reader.TagValuePair) (*v2_2.Document, error) {
|
|
parser := tvParser2_2{}
|
|
for _, tv := range tvs {
|
|
err := parser.parsePair2_2(tv.Tag, tv.Value)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
if parser.file != nil && parser.file.FileSPDXIdentifier == nullSpdxElementId2_2 {
|
|
return nil, fmt.Errorf("file with FileName %s does not have SPDX identifier", parser.file.FileName)
|
|
}
|
|
if parser.pkg != nil && parser.pkg.PackageSPDXIdentifier == nullSpdxElementId2_2 {
|
|
return nil, fmt.Errorf("package with PackageName %s does not have SPDX identifier", parser.pkg.PackageName)
|
|
}
|
|
return parser.doc, nil
|
|
}
|
|
|
|
func (parser *tvParser2_2) parsePair2_2(tag string, value string) error {
|
|
switch parser.st {
|
|
case psStart2_2:
|
|
return parser.parsePairFromStart2_2(tag, value)
|
|
case psCreationInfo2_2:
|
|
return parser.parsePairFromCreationInfo2_2(tag, value)
|
|
case psPackage2_2:
|
|
return parser.parsePairFromPackage2_2(tag, value)
|
|
case psFile2_2:
|
|
return parser.parsePairFromFile2_2(tag, value)
|
|
case psSnippet2_2:
|
|
return parser.parsePairFromSnippet2_2(tag, value)
|
|
case psOtherLicense2_2:
|
|
return parser.parsePairFromOtherLicense2_2(tag, value)
|
|
case psReview2_2:
|
|
return parser.parsePairFromReview2_2(tag, value)
|
|
default:
|
|
return fmt.Errorf("parser state %v not recognized when parsing (%s, %s)", parser.st, tag, value)
|
|
}
|
|
}
|
|
|
|
func (parser *tvParser2_2) parsePairFromStart2_2(tag string, value string) error {
|
|
// fail if not in Start parser state
|
|
if parser.st != psStart2_2 {
|
|
return fmt.Errorf("got invalid state %v in parsePairFromStart2_2", parser.st)
|
|
}
|
|
|
|
// create an SPDX Document data struct if we don't have one already
|
|
if parser.doc == nil {
|
|
parser.doc = &v2_2.Document{ExternalDocumentReferences: []v2_2.ExternalDocumentRef{}}
|
|
}
|
|
|
|
switch tag {
|
|
case "DocumentComment":
|
|
parser.doc.DocumentComment = value
|
|
case "SPDXVersion":
|
|
parser.doc.SPDXVersion = value
|
|
case "DataLicense":
|
|
parser.doc.DataLicense = value
|
|
case "SPDXID":
|
|
eID, err := extractElementID(value)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
parser.doc.SPDXIdentifier = eID
|
|
case "DocumentName":
|
|
parser.doc.DocumentName = value
|
|
case "DocumentNamespace":
|
|
parser.doc.DocumentNamespace = value
|
|
case "ExternalDocumentRef":
|
|
documentRefID, uri, alg, checksum, err := extractExternalDocumentReference(value)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
edr := v2_2.ExternalDocumentRef{
|
|
DocumentRefID: documentRefID,
|
|
URI: uri,
|
|
Checksum: common.Checksum{Algorithm: common.ChecksumAlgorithm(alg), Value: checksum},
|
|
}
|
|
parser.doc.ExternalDocumentReferences = append(parser.doc.ExternalDocumentReferences, edr)
|
|
default:
|
|
// move to Creation Info parser state
|
|
parser.st = psCreationInfo2_2
|
|
return parser.parsePairFromCreationInfo2_2(tag, value)
|
|
}
|
|
|
|
return nil
|
|
}
|