xref: /aosp_15_r20/external/spdx-tools/rdfloader/parser2v2/parse_license.go (revision ba677afa8f67bb56cbc794f4d0e378e0da058e16)
1*ba677afaSXin Li// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
2*ba677afaSXin Li
3*ba677afaSXin Lipackage parser2v2
4*ba677afaSXin Li
5*ba677afaSXin Liimport (
6*ba677afaSXin Li	"errors"
7*ba677afaSXin Li	"fmt"
8*ba677afaSXin Li	"strings"
9*ba677afaSXin Li
10*ba677afaSXin Li	gordfParser "github.com/spdx/gordf/rdfloader/parser"
11*ba677afaSXin Li	"github.com/spdx/gordf/rdfwriter"
12*ba677afaSXin Li)
13*ba677afaSXin Li
14*ba677afaSXin Li// AnyLicense is a baseClass for all the licenses
15*ba677afaSXin Li// All the types of licenses is a sub-type of AnyLicense,
16*ba677afaSXin Li// either directly or indirectly.
17*ba677afaSXin Li// This function acts as a mux for all the licenses. Based on the input, it
18*ba677afaSXin Li// decides which type of license it is and passes control to that type of
19*ba677afaSXin Li// license parser to parse the given input.
20*ba677afaSXin Lifunc (parser *rdfParser2_2) getAnyLicenseFromNode(node *gordfParser.Node) (AnyLicenseInfo, error) {
21*ba677afaSXin Li
22*ba677afaSXin Li	currState := parser.cache[node.ID]
23*ba677afaSXin Li	if currState == nil {
24*ba677afaSXin Li		// there is no entry about the state of current package node.
25*ba677afaSXin Li		// this is the first time we're seeing this node.
26*ba677afaSXin Li		parser.cache[node.ID] = &nodeState{
27*ba677afaSXin Li			object: nil, // not storing the object as we won't retrieve it later.
28*ba677afaSXin Li			Color:  WHITE,
29*ba677afaSXin Li		}
30*ba677afaSXin Li	} else if currState.Color == GREY {
31*ba677afaSXin Li		// we have already started parsing this license node.
32*ba677afaSXin Li		// We have a cyclic dependency!
33*ba677afaSXin Li		return nil, errors.New("Couldn't parse license: found a cyclic dependency on " + node.ID)
34*ba677afaSXin Li	}
35*ba677afaSXin Li
36*ba677afaSXin Li	// setting color of the state to grey to indicate that we've started to
37*ba677afaSXin Li	// parse this node once.
38*ba677afaSXin Li	parser.cache[node.ID].Color = GREY
39*ba677afaSXin Li
40*ba677afaSXin Li	// setting state color to black when we're done parsing this node.
41*ba677afaSXin Li	defer func() { parser.cache[node.ID].Color = BLACK }()
42*ba677afaSXin Li
43*ba677afaSXin Li	associatedTriples := rdfwriter.FilterTriples(parser.gordfParserObj.Triples, &node.ID, nil, nil)
44*ba677afaSXin Li	if len(associatedTriples) == 0 {
45*ba677afaSXin Li		// just a license uri string was found.
46*ba677afaSXin Li		return parser.getSpecialLicenseFromNode(node)
47*ba677afaSXin Li	}
48*ba677afaSXin Li
49*ba677afaSXin Li	// we have some attributes associated with the license node.
50*ba677afaSXin Li	nodeType, err := getNodeTypeFromTriples(associatedTriples, node)
51*ba677afaSXin Li	if err != nil {
52*ba677afaSXin Li		return nil, fmt.Errorf("error parsing license triple: %v", err)
53*ba677afaSXin Li	}
54*ba677afaSXin Li	switch nodeType {
55*ba677afaSXin Li	case SPDX_DISJUNCTIVE_LICENSE_SET:
56*ba677afaSXin Li		return parser.getDisjunctiveLicenseSetFromNode(node)
57*ba677afaSXin Li	case SPDX_CONJUNCTIVE_LICENSE_SET:
58*ba677afaSXin Li		return parser.getConjunctiveLicenseSetFromNode(node)
59*ba677afaSXin Li	case SPDX_EXTRACTED_LICENSING_INFO:
60*ba677afaSXin Li		return parser.getExtractedLicensingInfoFromNode(node)
61*ba677afaSXin Li	case SPDX_LISTED_LICENSE, SPDX_LICENSE:
62*ba677afaSXin Li		return parser.getLicenseFromNode(node)
63*ba677afaSXin Li	case SPDX_WITH_EXCEPTION_OPERATOR:
64*ba677afaSXin Li		return parser.getWithExceptionOperatorFromNode(node)
65*ba677afaSXin Li	case SPDX_OR_LATER_OPERATOR:
66*ba677afaSXin Li		return parser.getOrLaterOperatorFromNode(node)
67*ba677afaSXin Li	case SPDX_SIMPLE_LICENSING_INFO:
68*ba677afaSXin Li		return parser.getSimpleLicensingInfoFromNode(node)
69*ba677afaSXin Li	}
70*ba677afaSXin Li	return nil, fmt.Errorf("Unknown subTag (%s) found while parsing AnyLicense", nodeType)
71*ba677afaSXin Li}
72*ba677afaSXin Li
73*ba677afaSXin Lifunc (parser *rdfParser2_2) getLicenseExceptionFromNode(node *gordfParser.Node) (exception LicenseException, err error) {
74*ba677afaSXin Li	associatedTriples := rdfwriter.FilterTriples(parser.gordfParserObj.Triples, &node.ID, nil, nil)
75*ba677afaSXin Li	for _, triple := range associatedTriples {
76*ba677afaSXin Li		value := triple.Object.ID
77*ba677afaSXin Li		switch triple.Predicate.ID {
78*ba677afaSXin Li		case RDF_TYPE:
79*ba677afaSXin Li			continue
80*ba677afaSXin Li		case SPDX_LICENSE_EXCEPTION_ID:
81*ba677afaSXin Li			exception.licenseExceptionId = value
82*ba677afaSXin Li		case SPDX_LICENSE_EXCEPTION_TEXT:
83*ba677afaSXin Li			exception.licenseExceptionText = value
84*ba677afaSXin Li		case RDFS_SEE_ALSO:
85*ba677afaSXin Li			if !isUriValid(value) {
86*ba677afaSXin Li				return exception, fmt.Errorf("invalid uri (%s) for seeAlso attribute of LicenseException", value)
87*ba677afaSXin Li			}
88*ba677afaSXin Li			exception.seeAlso = value
89*ba677afaSXin Li		case SPDX_NAME:
90*ba677afaSXin Li			exception.name = value
91*ba677afaSXin Li		case SPDX_EXAMPLE:
92*ba677afaSXin Li			exception.example = value
93*ba677afaSXin Li		case RDFS_COMMENT:
94*ba677afaSXin Li			exception.comment = value
95*ba677afaSXin Li		default:
96*ba677afaSXin Li			return exception, fmt.Errorf("invalid predicate(%s) for LicenseException", triple.Predicate)
97*ba677afaSXin Li		}
98*ba677afaSXin Li	}
99*ba677afaSXin Li	return exception, nil
100*ba677afaSXin Li}
101*ba677afaSXin Li
102*ba677afaSXin Lifunc (parser *rdfParser2_2) getSimpleLicensingInfoFromNode(node *gordfParser.Node) (SimpleLicensingInfo, error) {
103*ba677afaSXin Li	simpleLicensingTriples := rdfwriter.FilterTriples(parser.gordfParserObj.Triples, &node.ID, nil, nil)
104*ba677afaSXin Li	return parser.getSimpleLicensingInfoFromTriples(simpleLicensingTriples)
105*ba677afaSXin Li}
106*ba677afaSXin Li
107*ba677afaSXin Lifunc (parser *rdfParser2_2) getWithExceptionOperatorFromNode(node *gordfParser.Node) (operator WithExceptionOperator, err error) {
108*ba677afaSXin Li	associatedTriples := rdfwriter.FilterTriples(parser.gordfParserObj.Triples, &node.ID, nil, nil)
109*ba677afaSXin Li	var memberFound bool
110*ba677afaSXin Li	for _, triple := range associatedTriples {
111*ba677afaSXin Li		switch triple.Predicate.ID {
112*ba677afaSXin Li		case RDF_TYPE:
113*ba677afaSXin Li			continue
114*ba677afaSXin Li		case SPDX_MEMBER:
115*ba677afaSXin Li			if memberFound {
116*ba677afaSXin Li				return operator,
117*ba677afaSXin Li					fmt.Errorf("more than one member found in the WithExceptionOperator (expected only 1)")
118*ba677afaSXin Li			}
119*ba677afaSXin Li			memberFound = true
120*ba677afaSXin Li			member, err := parser.getSimpleLicensingInfoFromNode(triple.Object)
121*ba677afaSXin Li			if err != nil {
122*ba677afaSXin Li				return operator, fmt.Errorf("error parsing member of a WithExceptionOperator: %v", err)
123*ba677afaSXin Li			}
124*ba677afaSXin Li			operator.member = member
125*ba677afaSXin Li		case SPDX_LICENSE_EXCEPTION:
126*ba677afaSXin Li			operator.licenseException, err = parser.getLicenseExceptionFromNode(triple.Object)
127*ba677afaSXin Li			if err != nil {
128*ba677afaSXin Li				return operator, fmt.Errorf("error parsing licenseException of WithExceptionOperator: %v", err)
129*ba677afaSXin Li			}
130*ba677afaSXin Li		default:
131*ba677afaSXin Li			return operator, fmt.Errorf("unknown predicate (%s) for a WithExceptionOperator", triple.Predicate.ID)
132*ba677afaSXin Li		}
133*ba677afaSXin Li	}
134*ba677afaSXin Li	return operator, nil
135*ba677afaSXin Li}
136*ba677afaSXin Li
137*ba677afaSXin Lifunc (parser *rdfParser2_2) getOrLaterOperatorFromNode(node *gordfParser.Node) (operator OrLaterOperator, err error) {
138*ba677afaSXin Li	associatedTriples := rdfwriter.FilterTriples(parser.gordfParserObj.Triples, &node.ID, nil, nil)
139*ba677afaSXin Li	n := len(associatedTriples)
140*ba677afaSXin Li	if n != 2 {
141*ba677afaSXin Li		return operator, fmt.Errorf("orLaterOperator must be associated with exactly one tag. found %v triples", n-1)
142*ba677afaSXin Li	}
143*ba677afaSXin Li	for _, triple := range associatedTriples {
144*ba677afaSXin Li		switch triple.Predicate.ID {
145*ba677afaSXin Li		case RDF_TYPE:
146*ba677afaSXin Li			continue
147*ba677afaSXin Li		case SPDX_MEMBER:
148*ba677afaSXin Li			operator.member, err = parser.getSimpleLicensingInfoFromNode(triple.Object)
149*ba677afaSXin Li			if err != nil {
150*ba677afaSXin Li				return operator, fmt.Errorf("error parsing simpleLicensingInfo of OrLaterOperator: %v", err)
151*ba677afaSXin Li			}
152*ba677afaSXin Li		default:
153*ba677afaSXin Li			return operator, fmt.Errorf("unknown predicate %s", triple.Predicate.ID)
154*ba677afaSXin Li		}
155*ba677afaSXin Li	}
156*ba677afaSXin Li	return operator, nil
157*ba677afaSXin Li}
158*ba677afaSXin Li
159*ba677afaSXin Li// SpecialLicense is a type of license which is not defined in any of the
160*ba677afaSXin Li// spdx documents, it is a type of license defined for the sake of brevity.
161*ba677afaSXin Li// It can be [NONE|NOASSERTION|LicenseRef-<string>]
162*ba677afaSXin Lifunc (parser *rdfParser2_2) getSpecialLicenseFromNode(node *gordfParser.Node) (lic SpecialLicense, err error) {
163*ba677afaSXin Li	uri := strings.TrimSpace(node.ID)
164*ba677afaSXin Li	switch uri {
165*ba677afaSXin Li	case SPDX_NONE_CAPS, SPDX_NONE_SMALL:
166*ba677afaSXin Li		return SpecialLicense{
167*ba677afaSXin Li			value: NONE,
168*ba677afaSXin Li		}, nil
169*ba677afaSXin Li	case SPDX_NOASSERTION_SMALL, SPDX_NOASSERTION_CAPS:
170*ba677afaSXin Li		return SpecialLicense{
171*ba677afaSXin Li			value: NOASSERTION,
172*ba677afaSXin Li		}, nil
173*ba677afaSXin Li	}
174*ba677afaSXin Li
175*ba677afaSXin Li	// the license is neither NONE nor NOASSERTION
176*ba677afaSXin Li	// checking if the license is among the standardLicenses
177*ba677afaSXin Li	licenseAbbreviation := getLastPartOfURI(uri)
178*ba677afaSXin Li	for _, stdLicense := range AllStandardLicenseIDS() {
179*ba677afaSXin Li		if licenseAbbreviation == stdLicense {
180*ba677afaSXin Li			return SpecialLicense{
181*ba677afaSXin Li				value: SpecialLicenseValue(stdLicense),
182*ba677afaSXin Li			}, nil
183*ba677afaSXin Li		}
184*ba677afaSXin Li	}
185*ba677afaSXin Li	return lic, fmt.Errorf("found a custom license uri (%s) without any associated fields", uri)
186*ba677afaSXin Li}
187*ba677afaSXin Li
188*ba677afaSXin Lifunc (parser *rdfParser2_2) getDisjunctiveLicenseSetFromNode(node *gordfParser.Node) (DisjunctiveLicenseSet, error) {
189*ba677afaSXin Li	licenseSet := DisjunctiveLicenseSet{
190*ba677afaSXin Li		members: []AnyLicenseInfo{},
191*ba677afaSXin Li	}
192*ba677afaSXin Li	for _, triple := range parser.nodeToTriples(node) {
193*ba677afaSXin Li		switch triple.Predicate.ID {
194*ba677afaSXin Li		case RDF_TYPE:
195*ba677afaSXin Li			continue
196*ba677afaSXin Li		case SPDX_MEMBER:
197*ba677afaSXin Li			member, err := parser.getAnyLicenseFromNode(triple.Object)
198*ba677afaSXin Li			if err != nil {
199*ba677afaSXin Li				return licenseSet, fmt.Errorf("error parsing disjunctive license set: %v", err)
200*ba677afaSXin Li			}
201*ba677afaSXin Li			licenseSet.members = append(licenseSet.members, member)
202*ba677afaSXin Li		}
203*ba677afaSXin Li	}
204*ba677afaSXin Li	return licenseSet, nil
205*ba677afaSXin Li}
206*ba677afaSXin Li
207*ba677afaSXin Lifunc (parser *rdfParser2_2) getConjunctiveLicenseSetFromNode(node *gordfParser.Node) (ConjunctiveLicenseSet, error) {
208*ba677afaSXin Li	licenseSet := ConjunctiveLicenseSet{
209*ba677afaSXin Li		members: []AnyLicenseInfo{},
210*ba677afaSXin Li	}
211*ba677afaSXin Li	for _, triple := range parser.nodeToTriples(node) {
212*ba677afaSXin Li		switch triple.Predicate.ID {
213*ba677afaSXin Li		case RDF_TYPE:
214*ba677afaSXin Li			continue
215*ba677afaSXin Li		case SPDX_MEMBER:
216*ba677afaSXin Li			member, err := parser.getAnyLicenseFromNode(triple.Object)
217*ba677afaSXin Li			if err != nil {
218*ba677afaSXin Li				return licenseSet, fmt.Errorf("error parsing conjunctive license set: %v", err)
219*ba677afaSXin Li			}
220*ba677afaSXin Li			licenseSet.members = append(licenseSet.members, member)
221*ba677afaSXin Li		default:
222*ba677afaSXin Li			return licenseSet, fmt.Errorf("unknown subTag for ConjunctiveLicenseSet: %s", triple.Predicate.ID)
223*ba677afaSXin Li		}
224*ba677afaSXin Li	}
225*ba677afaSXin Li	return licenseSet, nil
226*ba677afaSXin Li}
227*ba677afaSXin Li
228*ba677afaSXin Lifunc (parser *rdfParser2_2) getSimpleLicensingInfoFromTriples(triples []*gordfParser.Triple) (lic SimpleLicensingInfo, err error) {
229*ba677afaSXin Li	for _, triple := range triples {
230*ba677afaSXin Li		switch triple.Predicate.ID {
231*ba677afaSXin Li		case RDFS_COMMENT:
232*ba677afaSXin Li			lic.comment = triple.Object.ID
233*ba677afaSXin Li		case SPDX_LICENSE_ID:
234*ba677afaSXin Li			lic.licenseID = triple.Object.ID
235*ba677afaSXin Li		case SPDX_NAME:
236*ba677afaSXin Li			lic.name = triple.Object.ID
237*ba677afaSXin Li		case RDFS_SEE_ALSO:
238*ba677afaSXin Li			if !isUriValid(triple.Object.ID) {
239*ba677afaSXin Li				return lic, fmt.Errorf("%s is not a valid uri for seeAlso attribute of a License", triple.Object.ID)
240*ba677afaSXin Li			}
241*ba677afaSXin Li			lic.seeAlso = append(lic.seeAlso, triple.Object.ID)
242*ba677afaSXin Li		case SPDX_EXAMPLE:
243*ba677afaSXin Li			lic.example = triple.Object.ID
244*ba677afaSXin Li		case RDF_TYPE:
245*ba677afaSXin Li			continue
246*ba677afaSXin Li		default:
247*ba677afaSXin Li			return lic, fmt.Errorf("unknown predicate(%s) for simple licensing info", triple.Predicate)
248*ba677afaSXin Li		}
249*ba677afaSXin Li	}
250*ba677afaSXin Li	return lic, nil
251*ba677afaSXin Li}
252*ba677afaSXin Li
253*ba677afaSXin Lifunc (parser *rdfParser2_2) getLicenseFromNode(node *gordfParser.Node) (lic License, err error) {
254*ba677afaSXin Li	associatedTriples := rdfwriter.FilterTriples(parser.gordfParserObj.Triples, &node.ID, nil, nil)
255*ba677afaSXin Li	var restTriples []*gordfParser.Triple
256*ba677afaSXin Li	for _, triple := range associatedTriples {
257*ba677afaSXin Li		value := triple.Object.ID
258*ba677afaSXin Li		switch triple.Predicate.ID {
259*ba677afaSXin Li		case SPDX_IS_OSI_APPROVED:
260*ba677afaSXin Li			lic.isOsiApproved, err = boolFromString(value)
261*ba677afaSXin Li			if err != nil {
262*ba677afaSXin Li				return lic, fmt.Errorf("error parsing isOsiApproved attribute of a License: %v", err)
263*ba677afaSXin Li			}
264*ba677afaSXin Li		case SPDX_LICENSE_TEXT:
265*ba677afaSXin Li			lic.licenseText = value
266*ba677afaSXin Li		case SPDX_STANDARD_LICENSE_HEADER:
267*ba677afaSXin Li			lic.standardLicenseHeader = value
268*ba677afaSXin Li		case SPDX_STANDARD_LICENSE_TEMPLATE:
269*ba677afaSXin Li			lic.standardLicenseTemplate = value
270*ba677afaSXin Li		case SPDX_STANDARD_LICENSE_HEADER_TEMPLATE:
271*ba677afaSXin Li			lic.standardLicenseHeaderTemplate = value
272*ba677afaSXin Li		case SPDX_IS_DEPRECATED_LICENSE_ID:
273*ba677afaSXin Li			lic.isDeprecatedLicenseID, err = boolFromString(value)
274*ba677afaSXin Li			if err != nil {
275*ba677afaSXin Li				return lic, fmt.Errorf("error parsing isDeprecatedLicenseId attribute of a License: %v", err)
276*ba677afaSXin Li			}
277*ba677afaSXin Li		case SPDX_IS_FSF_LIBRE:
278*ba677afaSXin Li			lic.isFsfLibre, err = boolFromString(value)
279*ba677afaSXin Li			if err != nil {
280*ba677afaSXin Li				return lic, fmt.Errorf("error parsing isFsfLibre attribute of a License: %v", err)
281*ba677afaSXin Li			}
282*ba677afaSXin Li		default:
283*ba677afaSXin Li			restTriples = append(restTriples, triple)
284*ba677afaSXin Li		}
285*ba677afaSXin Li	}
286*ba677afaSXin Li	lic.SimpleLicensingInfo, err = parser.getSimpleLicensingInfoFromTriples(restTriples)
287*ba677afaSXin Li	if err != nil {
288*ba677afaSXin Li		return lic, fmt.Errorf("error setting simple licensing information of a License: %s", err)
289*ba677afaSXin Li	}
290*ba677afaSXin Li	return lic, nil
291*ba677afaSXin Li}
292