1use super::HasName;
7use crate::load::ModuleLoader;
8use crate::model::definitions::Definition;
9use crate::model::identifiers::IdentifierReference;
10use crate::model::modules::Module;
11use crate::store::ModuleStore;
12
13pub trait MaybeIncomplete {
18 fn is_incomplete(&self, top: &Module, cache: &impl ModuleStore) -> bool;
19}
20
21pub trait Validate {
22 fn validate(
23 &self,
24 top: &Module,
25 cache: &impl ModuleStore,
26 loader: &impl ModuleLoader,
27 check_constraints: bool,
28 );
29}
30
31pub fn find_definition<'a>(
36 name: &IdentifierReference,
37 current: &'a Module,
38 cache: &'a impl ModuleStore,
39) -> Option<&'a Definition> {
40 cache.resolve_or_in(name, current.name())
41}
42
43#[cfg(feature = "terms")]
71pub mod terms {
72 use std::collections::HashMap;
73
74 use crate::load::ModuleLoader;
75 use crate::model::annotations::*;
76 use crate::model::constraints::*;
77 use crate::model::definitions::*;
78 use crate::model::identifiers::*;
79 use crate::model::members::*;
80 use crate::model::modules::*;
81 use crate::model::values::*;
82 use crate::model::*;
83 use sdml_errors::diagnostics::functions::deprecated_term_used;
84 use sdml_errors::Error;
85 use serde::{Deserialize, Serialize};
86
87 #[derive(Clone, Debug, Deserialize, Serialize)]
92 pub struct TermSet {
93 name: String,
94 #[serde(skip_serializing_if = "Option::is_none")]
95 version: Option<String>,
96 #[serde(skip_serializing_if = "Option::is_none")]
97 description: Option<String>,
98 terms: HashMap<String, Term>,
99 }
100
101 #[derive(Clone, Debug, Deserialize, Serialize)]
102 pub struct Term {
103 #[serde(skip_serializing_if = "Option::is_none", with = "serde_regex")]
104 regex: Option<regex::Regex>,
105 alternative_terms: Vec<String>,
106 #[serde(skip_serializing_if = "Option::is_none")]
107 reason: Option<String>,
108 }
109
110 const DEFAULT_RULES: &str = include_str!("default_terms.json");
115
116 pub fn default_term_set() -> Result<TermSet, Error> {
117 Ok(serde_json::from_str(DEFAULT_RULES).unwrap())
118 }
119
120 pub fn validate_module_terms(module: &Module, term_set: &TermSet, loader: &impl ModuleLoader) {
121 let mut validator = Validator::from(term_set);
122 module.name().validate_terms(&mut validator, module, loader);
123 for annotation in module.body().annotations() {
124 annotation.validate_terms(&mut validator, module, loader);
125 }
126 for definition in module.body().definitions() {
127 definition.validate_terms(&mut validator, module, loader);
128 }
129 }
130
131 #[derive(Clone, Debug)]
136 struct TermInfo<'a> {
137 regex: regex::Regex,
138 alternative_terms: &'a Vec<String>,
139 reason: &'a Option<String>,
140 }
141
142 #[derive(Clone, Debug)]
143 struct Validator<'a> {
144 term_map: HashMap<String, TermInfo<'a>>,
145 seen: HashSet<String>,
146 }
147
148 impl<'a> From<&'a TermSet> for Validator<'a> {
153 fn from(term_set: &'a TermSet) -> Self {
154 let mut term_map: HashMap<String, TermInfo<'a>> = Default::default();
155 for (term, info) in &term_set.terms {
156 let regex = if let Some(regex) = &info.regex {
157 regex.clone()
158 } else {
159 regex::Regex::new(&format!("(?i)\\b{}\\b", term)).unwrap()
160 };
161 let new_info = TermInfo {
162 regex,
163 alternative_terms: &info.alternative_terms,
164 reason: &info.reason,
165 };
166 term_map.insert(term.clone(), new_info);
167 }
168 Self {
169 term_map,
170 seen: Default::default(),
171 }
172 }
173 }
174
175 impl Validator<'_> {
176 fn check_for_matches<S>(
177 &mut self,
178 value: S,
179 span: Option<&Span>,
180 top: &Module,
181 loader: &impl ModuleLoader,
182 ) where
183 S: Into<String>,
184 {
185 let value = value.into();
186 if self.seen.insert(value.clone()) {
187 for (term, info) in &self.term_map {
188 if info.regex.is_match(value.as_ref()) {
189 loader
190 .report(&deprecated_term_used(
191 top.file_id().copied().unwrap_or_default(),
192 span.map(|span| span.byte_range()),
193 &value,
194 term,
195 info.alternative_terms,
196 info.reason.as_ref(),
197 ))
198 .unwrap()
199 }
200 }
201 }
202 }
203 }
204
205 trait ValidateTerms {
208 fn validate_terms(
209 &self,
210 validator: &mut Validator<'_>,
211 top: &Module,
212 loader: &impl ModuleLoader,
213 );
214 }
215
216 impl ValidateTerms for Identifier {
217 fn validate_terms(
218 &self,
219 validator: &mut Validator<'_>,
220 top: &Module,
221 loader: &impl ModuleLoader,
222 ) {
223 validator.check_for_matches(self, self.source_span(), top, loader);
224 }
225 }
226
227 impl ValidateTerms for QualifiedIdentifier {
228 fn validate_terms(
229 &self,
230 validator: &mut Validator<'_>,
231 top: &Module,
232 loader: &impl ModuleLoader,
233 ) {
234 self.module().validate_terms(validator, top, loader);
235 self.member().validate_terms(validator, top, loader);
236 }
237 }
238
239 impl ValidateTerms for IdentifierReference {
240 fn validate_terms(
241 &self,
242 validator: &mut Validator<'_>,
243 top: &Module,
244 loader: &impl ModuleLoader,
245 ) {
246 match self {
247 Self::Identifier(v) => v.validate_terms(validator, top, loader),
248 Self::QualifiedIdentifier(v) => v.validate_terms(validator, top, loader),
249 }
250 }
251 }
252
253 impl ValidateTerms for Annotation {
254 fn validate_terms(
255 &self,
256 validator: &mut Validator<'_>,
257 top: &Module,
258 loader: &impl ModuleLoader,
259 ) {
260 match self {
261 Self::Property(v) => v.validate_terms(validator, top, loader),
262 Self::Constraint(v) => v.validate_terms(validator, top, loader),
263 }
264 }
265 }
266
267 impl ValidateTerms for AnnotationProperty {
268 fn validate_terms(
269 &self,
270 validator: &mut Validator<'_>,
271 top: &Module,
272 loader: &impl ModuleLoader,
273 ) {
274 self.name_reference().validate_terms(validator, top, loader);
275 self.value().validate_terms(validator, top, loader);
276 }
277 }
278
279 impl ValidateTerms for Value {
280 fn validate_terms(
281 &self,
282 validator: &mut Validator<'_>,
283 top: &Module,
284 loader: &impl ModuleLoader,
285 ) {
286 match self {
287 Self::Simple(v) => v.validate_terms(validator, top, loader),
288 Self::ValueConstructor(v) => v.validate_terms(validator, top, loader),
289 Self::Mapping(v) => v.validate_terms(validator, top, loader),
290 Self::Reference(v) => v.validate_terms(validator, top, loader),
291 Self::List(v) => v.validate_terms(validator, top, loader),
292 }
293 }
294 }
295
296 impl ValidateTerms for SimpleValue {
297 fn validate_terms(
298 &self,
299 validator: &mut Validator<'_>,
300 top: &Module,
301 loader: &impl ModuleLoader,
302 ) {
303 if let SimpleValue::String(value) = self {
304 validator.check_for_matches(value.value(), value.source_span(), top, loader);
305 }
306 }
307 }
308
309 impl ValidateTerms for ValueConstructor {
310 fn validate_terms(
311 &self,
312 validator: &mut Validator<'_>,
313 top: &Module,
314 loader: &impl ModuleLoader,
315 ) {
316 self.type_name().validate_terms(validator, top, loader);
317 self.value().validate_terms(validator, top, loader);
318 }
319 }
320
321 impl ValidateTerms for SequenceOfValues {
322 fn validate_terms(
323 &self,
324 validator: &mut Validator<'_>,
325 top: &Module,
326 loader: &impl ModuleLoader,
327 ) {
328 for value in self.iter() {
329 value.validate_terms(validator, top, loader);
330 }
331 }
332 }
333
334 impl ValidateTerms for SequenceMember {
335 fn validate_terms(
336 &self,
337 validator: &mut Validator<'_>,
338 top: &Module,
339 loader: &impl ModuleLoader,
340 ) {
341 match self {
342 Self::Simple(v) => v.validate_terms(validator, top, loader),
343 Self::ValueConstructor(v) => v.validate_terms(validator, top, loader),
344 Self::Reference(v) => v.validate_terms(validator, top, loader),
345 Self::Mapping(v) => v.validate_terms(validator, top, loader),
346 }
347 }
348 }
349
350 impl ValidateTerms for MappingValue {
351 fn validate_terms(
352 &self,
353 validator: &mut Validator<'_>,
354 top: &Module,
355 loader: &impl ModuleLoader,
356 ) {
357 self.domain().validate_terms(validator, top, loader);
358 self.range().validate_terms(validator, top, loader);
359 }
360 }
361
362 impl ValidateTerms for AnnotationOnlyBody {
363 fn validate_terms(
364 &self,
365 validator: &mut Validator<'_>,
366 top: &Module,
367 loader: &impl ModuleLoader,
368 ) {
369 for annotation in self.annotations() {
370 annotation.validate_terms(validator, top, loader);
371 }
372 }
373 }
374
375 impl ValidateTerms for Constraint {
376 fn validate_terms(
377 &self,
378 validator: &mut Validator<'_>,
379 top: &Module,
380 loader: &impl ModuleLoader,
381 ) {
382 self.name().validate_terms(validator, top, loader);
383 match self.body() {
384 ConstraintBody::Informal(v) => v.validate_terms(validator, top, loader),
385 ConstraintBody::Formal(v) => v.validate_terms(validator, top, loader),
386 }
387 }
388 }
389
390 impl ValidateTerms for ControlledLanguageString {
391 fn validate_terms(
392 &self,
393 validator: &mut Validator<'_>,
394 top: &Module,
395 loader: &impl ModuleLoader,
396 ) {
397 validator.check_for_matches(self.value(), self.source_span(), top, loader);
398 }
399 }
400
401 impl ValidateTerms for FormalConstraint {
402 fn validate_terms(
403 &self,
404 _validator: &mut Validator<'_>,
405 _top: &Module,
406 _loader: &impl ModuleLoader,
407 ) {
408 todo!()
409 }
410 }
411
412 impl ValidateTerms for Definition {
413 fn validate_terms(
414 &self,
415 validator: &mut Validator<'_>,
416 top: &Module,
417 loader: &impl ModuleLoader,
418 ) {
419 match self {
420 Self::Datatype(v) => v.validate_terms(validator, top, loader),
421 Self::Entity(v) => v.validate_terms(validator, top, loader),
422 Self::Enum(v) => v.validate_terms(validator, top, loader),
423 Self::Event(v) => v.validate_terms(validator, top, loader),
424 Self::Property(v) => v.validate_terms(validator, top, loader),
425 Self::Rdf(v) => v.validate_terms(validator, top, loader),
426 Self::Structure(v) => v.validate_terms(validator, top, loader),
427 Self::TypeClass(v) => v.validate_terms(validator, top, loader),
428 Self::Union(v) => v.validate_terms(validator, top, loader),
429 }
430 }
431 }
432
433 impl ValidateTerms for DatatypeDef {
434 fn validate_terms(
435 &self,
436 validator: &mut Validator<'_>,
437 top: &Module,
438 loader: &impl ModuleLoader,
439 ) {
440 self.name().validate_terms(validator, top, loader);
441 self.base_type().validate_terms(validator, top, loader);
442 if let Some(body) = self.body() {
443 body.validate_terms(validator, top, loader);
444 }
445 }
446 }
447
448 impl ValidateTerms for EntityDef {
449 fn validate_terms(
450 &self,
451 validator: &mut Validator<'_>,
452 top: &Module,
453 loader: &impl ModuleLoader,
454 ) {
455 self.name().validate_terms(validator, top, loader);
456 if let Some(body) = self.body() {
457 for annotation in body.annotations() {
458 annotation.validate_terms(validator, top, loader);
459 }
460 for member in body.members() {
461 member.validate_terms(validator, top, loader);
462 }
463 }
464 }
465 }
466
467 impl ValidateTerms for EnumDef {
468 fn validate_terms(
469 &self,
470 validator: &mut Validator<'_>,
471 top: &Module,
472 loader: &impl ModuleLoader,
473 ) {
474 self.name().validate_terms(validator, top, loader);
475 if let Some(body) = self.body() {
476 for annotation in body.annotations() {
477 annotation.validate_terms(validator, top, loader);
478 }
479 for variant in body.variants() {
480 variant.validate_terms(validator, top, loader);
481 }
482 }
483 }
484 }
485
486 impl ValidateTerms for ValueVariant {
487 fn validate_terms(
488 &self,
489 validator: &mut Validator<'_>,
490 top: &Module,
491 loader: &impl ModuleLoader,
492 ) {
493 self.name().validate_terms(validator, top, loader);
494 if let Some(body) = self.body() {
495 for annotation in body.annotations() {
496 annotation.validate_terms(validator, top, loader);
497 }
498 }
499 }
500 }
501
502 impl ValidateTerms for EventDef {
503 fn validate_terms(
504 &self,
505 validator: &mut Validator<'_>,
506 top: &Module,
507 loader: &impl ModuleLoader,
508 ) {
509 self.name().validate_terms(validator, top, loader);
510 self.event_source().validate_terms(validator, top, loader);
511 if let Some(body) = self.body() {
512 for annotation in body.annotations() {
513 annotation.validate_terms(validator, top, loader);
514 for member in body.members() {
515 member.validate_terms(validator, top, loader);
516 }
517 }
518 }
519 }
520 }
521
522 impl ValidateTerms for PropertyDef {
523 fn validate_terms(
524 &self,
525 validator: &mut Validator<'_>,
526 top: &Module,
527 loader: &impl ModuleLoader,
528 ) {
529 self.member_def().validate_terms(validator, top, loader);
530 }
531 }
532
533 impl ValidateTerms for RdfDef {
534 fn validate_terms(
535 &self,
536 validator: &mut Validator<'_>,
537 top: &Module,
538 loader: &impl ModuleLoader,
539 ) {
540 self.name().validate_terms(validator, top, loader);
541 for annotation in self.body().annotations() {
542 annotation.validate_terms(validator, top, loader);
543 }
544 }
545 }
546
547 impl ValidateTerms for StructureDef {
548 fn validate_terms(
549 &self,
550 validator: &mut Validator<'_>,
551 top: &Module,
552 loader: &impl ModuleLoader,
553 ) {
554 self.name().validate_terms(validator, top, loader);
555 if let Some(body) = self.body() {
556 for annotation in body.annotations() {
557 annotation.validate_terms(validator, top, loader);
558 }
559 for member in body.members() {
560 member.validate_terms(validator, top, loader);
561 }
562 }
563 }
564 }
565
566 impl ValidateTerms for TypeClassDef {
567 fn validate_terms(
568 &self,
569 validator: &mut Validator<'_>,
570 top: &Module,
571 loader: &impl ModuleLoader,
572 ) {
573 self.name().validate_terms(validator, top, loader);
574 if let Some(body) = self.body() {
575 for annotation in body.annotations() {
576 annotation.validate_terms(validator, top, loader);
577 }
578 }
579 todo!("validate all")
580 }
581 }
582
583 impl ValidateTerms for UnionDef {
584 fn validate_terms(
585 &self,
586 validator: &mut Validator<'_>,
587 top: &Module,
588 loader: &impl ModuleLoader,
589 ) {
590 self.name().validate_terms(validator, top, loader);
591 if let Some(body) = self.body() {
592 for annotation in body.annotations() {
593 annotation.validate_terms(validator, top, loader);
594 }
595 for variant in body.variants() {
596 variant.validate_terms(validator, top, loader);
597 }
598 }
599 }
600 }
601
602 impl ValidateTerms for TypeVariant {
603 fn validate_terms(
604 &self,
605 validator: &mut Validator<'_>,
606 top: &Module,
607 loader: &impl ModuleLoader,
608 ) {
609 self.name_reference().validate_terms(validator, top, loader);
610 if let Some(rename) = self.rename() {
611 rename.validate_terms(validator, top, loader);
612 }
613 if let Some(body) = self.body() {
614 for annotation in body.annotations() {
615 annotation.validate_terms(validator, top, loader);
616 }
617 }
618 }
619 }
620
621 impl ValidateTerms for Member {
622 fn validate_terms(
623 &self,
624 validator: &mut Validator<'_>,
625 top: &Module,
626 loader: &impl ModuleLoader,
627 ) {
628 match self.kind() {
629 MemberKind::Reference(v) => v.validate_terms(validator, top, loader),
630 MemberKind::Definition(v) => v.validate_terms(validator, top, loader),
631 }
632 }
633 }
634
635 impl ValidateTerms for MemberDef {
636 fn validate_terms(
637 &self,
638 validator: &mut Validator<'_>,
639 top: &Module,
640 loader: &impl ModuleLoader,
641 ) {
642 self.name().validate_terms(validator, top, loader);
643 self.target_type().validate_terms(validator, top, loader);
644 if let Some(body) = self.body() {
645 body.validate_terms(validator, top, loader);
646 }
647 }
648 }
649
650 impl ValidateTerms for TypeReference {
651 fn validate_terms(
652 &self,
653 validator: &mut Validator<'_>,
654 top: &Module,
655 loader: &impl ModuleLoader,
656 ) {
657 match self {
658 Self::Unknown => {}
659 Self::Type(v) => v.validate_terms(validator, top, loader),
660 Self::MappingType(v) => {
661 v.domain().validate_terms(validator, top, loader);
662 v.range().validate_terms(validator, top, loader);
663 }
664 }
665 }
666 }
667}