HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
context.h
Go to the documentation of this file.
1 //
2 // Copyright 2024 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_USD_VALIDATION_USD_VALIDATION_CONTEXT_H
8 #define PXR_USD_VALIDATION_USD_VALIDATION_CONTEXT_H
9 
10 /// \file
11 
12 #include "pxr/pxr.h"
13 #include "pxr/base/plug/plugin.h"
15 #include "pxr/base/tf/token.h"
16 #include "pxr/usd/usd/primRange.h"
21 
22 #include <mutex>
23 
25 
26 class TfType;
27 class WorkDispatcher;
29 
30 /// \class UsdValidationContext
31 ///
32 /// UsdValidationContext provides an interface for managing and running
33 /// validators on USD layers, stages, or prims.
34 ///
35 /// The UsdValidationContext can be constructed using various methods to select
36 /// validators by keywords, schema types, plugins, or pre-selected sets of
37 /// validatorMetadata or validators.
38 ///
39 /// Pre-selected set of UsdValidationValidatorMetadata or
40 /// UsdValidationValidators can be gathered using various UsdValidationRegistry
41 /// APIs. For example, a client can construct a validation context by providing
42 /// validator metadata for all usdGeom plugin validators but excluding all
43 /// validators metadata belonging to a specific schemaType like UsdGeomPoints.
44 ///
45 /// When schema type validators are provided, an appropriate hierarchy of schema
46 /// validators are included in the selected list of validators. For example,
47 /// if UsdGeomSphere schema type is provided, validators for UsdGeomGprim,
48 /// UsdGeomBoundable, UsdGeomXformable, and UsdGeomImageable are also included.
49 ///
50 /// Clients can also provide \p includeAllAncestors flag (defaults to true) to
51 /// also select validators from all ancestor TfType for any selected schemaType
52 /// validator when initializing a UsdValidationContext using \p keywords and
53 /// of the provided schemaType(s) validators.\p metadata constructors.
54 ///
55 /// Once a context is created and the list of validators to be run is populated,
56 /// clients can simply run the validators on a layer, stage or a set of prims.
57 /// All validators with UsdValidateLayerTaskFn, UsdValidateStageTaskFn or
58 /// UsdValidatePrimTaskFn will be run in a parallel and UsdValidationError will
59 /// be collected for each validator.
60 ///
61 /// Note that initializing a UsdValidationContext can result in loading new
62 /// plugins, if the validators are not already loaded.
63 ///
64 /// UsdValidationContext::Validate() call could initiate a stage traversal, and
65 /// appropriately call various validation tasks on the validators.
66 ///
67 /// UsdValidationContext does not hold any state about the validation errors
68 /// collected during validation. The errors are returned as a vector of
69 /// UsdValidationError when Validate() is called.
70 ///
71 /// \sa UsdValidationRegistry
72 /// \sa UsdValidationValidator
73 /// \sa UsdValidationError
74 ///
76 {
77 public:
78  /// Create a UsdValidationContext by collecting validators using the
79  /// specified keywords.
80  ///
81  /// \param keywords
82  /// A vector of keywords to select validators from. All validators having
83  /// these keywords will get loaded and included in the selected group of
84  /// validators to be run for validation. It will also collect validators
85  /// from a UsdValidationValidatorSuite if the suite also contains the
86  /// specified keywords.
87  ///
88  /// \param includeAllAncestors
89  /// An optional parameter to include all validators from ancestor TfTypes
90  /// for any schema type validators found, default is `true`.
92  explicit UsdValidationContext(const TfTokenVector &keywords,
93  bool includeAllAncestors = true);
94 
95  /// Create a UsdValidationContext by collecting validators using the
96  /// specified vector of plugins.
97  ///
98  /// \param plugins
99  /// A vector of plugins to select validators from. All validators belonging
100  /// to the specified plugins will get loaded and included in the selected
101  /// group of validators to be run for validation. It will also collect
102  /// validators from a UsdValidationValidatorSuite if the suite belongs to
103  /// the specified plugins
104  ///
105  /// \param includeAllAncestors
106  /// An optional parameter to include all validators from ancestor TfTypes
107  /// for any schema type validators found, default is `true`.
109  explicit UsdValidationContext(const PlugPluginPtrVector &plugins,
110  bool includeAllAncestors = true);
111 
112  /// Create a UsdValidationContext by collecting validators using the
113  /// specified vector of validator metadata.
114  ///
115  /// \param metadata
116  /// A vector of validator metadata. All validators corresponding to the
117  /// metadata will get loaded and included in the selected group of
118  /// validators to be run for validation. It will also collect validators
119  /// from a UsdValidationValidatorSuite if a metadata has isSuite set to
120  /// true.
121  ///
122  /// \param includeAllAncestors
123  /// An optional parameter to include all validators from ancestor TfTypes
124  /// for any schema type validators found, default is `true`.
126  explicit UsdValidationContext(
127  const UsdValidationValidatorMetadataVector &metadata,
128  bool includeAllAncestors = true);
129 
130  /// Create a UsdValidationContext by collecting validators using the
131  /// specified schema types.
132  ///
133  /// \param schemaTypes
134  /// A vector of schema types to select validators from. All validators
135  /// corresponding to the provided schemaTypes are included in the selected
136  /// group of validators to be run for validation.
137  ///
138  /// Note that all validators corresponding to the ancestor TfTypes for the
139  /// provided schemaTypes are included in the selected group of validators.
141  explicit UsdValidationContext(const std::vector<TfType> &schemaTypes);
142 
143  /// Create a UsdValidationContext by collecting validators using the
144  /// specified vector of validators.
145  ///
146  /// \param validators
147  /// A vector of explicit validators.
149  explicit UsdValidationContext(
150  const std::vector<const UsdValidationValidator *> &validators);
151 
152  /// Create a UsdValidationContext by collecting validators from the
153  /// specified vector of validator suites.
154  ///
155  /// \param suites
156  /// A vector of validator suites.
158  explicit UsdValidationContext(
159  const std::vector<const UsdValidationValidatorSuite *> &suites);
160 
161  /// Run validation on the given valid \p layer by executing the selected
162  /// validators for this UsdValidationContext; Returns a vector of errors
163  /// collected during validation.
164  ///
165  /// Only layer validators in the selected group of validators will be run on
166  /// the given layer.
167  ///
168  /// All the validators run in parallel. Any resulting errors are collected
169  /// in the returned vector.
170  ///
171  /// Note that it's the responsibility of the caller to maintain the lifetime
172  /// of the layer during the lifetime of the this validation context.
173  /// UsdValidationErrorSites in the returned vector will reference the layer
174  /// and hence are valid only as long as the layer is valid.
175  ///
176  /// A coding error is issued if the layer being validated is not valid.
178  UsdValidationErrorVector Validate(const SdfLayerHandle &layer) const;
179 
180  /// Run validation on the given valid \p stage by executing the selected
181  /// validators for this UsdValidationContext; Returns a vector of errors
182  ///
183  /// Any Layer validators in the selected group of validators will be run on
184  /// the layers reachable from the stage. In addition to that any Stage
185  /// validators will also be run on the given stage. The stage will also be
186  /// traversed to run prim and schema type validators on all the prims in the
187  /// stage. \p predicate will be used to traverse the prims to be validated.
188  ///
189  /// PrimValidators and StageValidators will be passed the provided
190  /// \p timeRange.
191  ///
192  /// All the validators run in parallel. Any resulting errors are collected
193  /// in the returned vector.
194  ///
195  /// Note that it's the responsibility of the caller to maintain the lifetime
196  /// of the stage during the lifetime of the this validation context.
197  /// UsdValidationErrorSites in the returned vector will reference the stage
198  /// and hence are valid only as long as the stage is valid.
199  ///
200  /// A coding error is issued if the stage being validated is not valid.
203  const UsdStagePtr &stage,
204  const Usd_PrimFlagsPredicate &predicate,
205  const UsdValidationTimeRange &timeRange) const;
206 
207  /// Run validation on the given valid \p stage by executing the selected
208  /// validators for this UsdValidationContext; Returns a vector of errors
209  ///
210  /// StageValidators and PrimValidators will also be passed the default
211  /// UsdValidationTimeRange, which uses GfInterval::GetFullInterval()
212  /// as the time interval.
213  ///
214  /// \sa UsdValidationContext::Validate(const UsdStagePtr &stage,
215  /// const Usd_PrimFlagsPredicate &predicate) const
218  const UsdStagePtr &stage,
219  const Usd_PrimFlagsPredicate &predicate) const;
220 
221  /// Run validation on the given valid \p stage by executing the selected
222  /// validators for this UsdValidationContext; Returns a vector of errors
223  ///
224  /// \ref UsdTraverseInstanceProxies "Instance Proxy predicate" is used to
225  /// traverse the prims to be validated in this overload.
226  ///
227  /// StageValidators and PrimValidators will also be passed the default
228  /// UsdValidationTimeRange, which uses GfInterval::GetFullInterval()
229  /// as the time interval.
230  ///
231  /// \sa UsdValidationContext::Validate(const UsdStagePtr &stage,
232  /// const Usd_PrimFlagsPredicate &predicate) const
234  UsdValidationErrorVector Validate(const UsdStagePtr &stage) const;
235 
236  /// Run validation on the given valid \p stage by executing the selected
237  /// validators for this UsdValidationContext; Returns a vector of errors
238  ///
239  /// PrimValidators and StageValidators will be passed the provided
240  /// \p timeRange.
241  ///
242  /// \ref UsdTraverseInstanceProxies "Instance Proxy predicate" is used to
243  /// traverse the prims to be validated in this overload.
244  ///
245  /// \sa UsdValidationContext::Validate(const UsdStagePtr &stage,
246  /// const Usd_PrimFlagsPredicate &predicate) const
249  const UsdStagePtr &stage,
250  const UsdValidationTimeRange &timeRange) const;
251 
252  /// Run validation on the given valid \p stage by executing the selected
253  /// validators for this UsdValidationContext; Returns a vector of errors
254  ///
255  /// PrimValidators and StageValidators will be run on all \p timeCodes.
256  /// If \p timeCodes is empty, then no validation will be performed.
257  ///
258  /// Note that non-time dependent validators will be run only once and time
259  /// dependent validators will be run at all the provided timeCodes.
260  ///
261  /// \sa UsdValidationContext::Validate(const UsdStagePtr &stage,
262  /// const Usd_PrimFlagsPredicate &predicate) const
265  const UsdStagePtr &stage,
266  const Usd_PrimFlagsPredicate &predicate,
267  const std::vector<UsdTimeCode> &timeCodes) const;
268 
269  /// Run validation on the given valid \p stage by executing the selected
270  /// validators for this UsdValidationContext; Returns a vector of errors
271  ///
272  /// PrimValidators and StageValidators will be run on all \p timeCodes.
273  /// If \p timeCodes is empty, then no validation will be performed.
274  ///
275  /// Note that non-time dependent validators will be run only once and time
276  /// dependent validators will be run at all the provided timeCodes.
277  ///
278  /// \ref UsdTraverseInstanceProxies "Instance Proxy predicate" is used to
279  /// traverse the prims to be validated in this overload.
280  ///
281  /// \sa UsdValidationContext::Validate(const UsdStagePtr &stage,
282  /// const Usd_PrimFlagsPredicate &predicate) const
285  const UsdStagePtr &stage,
286  const std::vector<UsdTimeCode> &timeCodes) const;
287 
288  /// Run validation on the given valid \p prims by executing the selected
289  /// validators for this UsdValidationContext; Returns a vector of errors
290  /// collected during validation.
291  ///
292  /// Prim and Schema type validators will be run on the given prims using
293  /// UsdValidationTimeRange(), if \p timeRange is not provided.
294  ///
295  /// All the validators run in parallel. Any resulting errors are collected
296  /// in the returned vector.
297  ///
298  /// Note that it's the responsibility of the caller to maintain the lifetime
299  /// of the stage that the prims belong to, during the lifetime of the
300  /// this validation context.
301  ///
302  /// A coding error is issued if any of the prims being validated are
303  /// invalid.
306  const std::vector<UsdPrim> &prims,
307  const UsdValidationTimeRange &timeRange = {}) const;
308 
309  /// Run validation on the given valid \p prims by executing the selected
310  /// validators for this UsdValidationContext; Returns a vector of errors
311  /// collected during validation.
312  ///
313  /// Prim and Schema type validators will be run on the given prims using
314  /// UsdValidationTimeRange(), if \p timeRange is not provided.
315  ///
316  /// Note that it's the responsibility of the caller to maintain the lifetime
317  /// of the stage that the prims belong to, during the lifetime of the
318  /// this validation context.
319  ///
320  /// All the validators run in parallel. Any resulting errors are collected
321  /// in the returned vector.
322  ///
323  /// A coding error is issued if any of the prims being validated are
324  /// invalid.
327  const UsdPrimRange &prims,
328  const UsdValidationTimeRange &timeRange = {}) const;
329 
330  /// Run validation on the given valid \p prims by executing the selected
331  /// validators for this UsdValidationContext; Returns a vector of errors
332  /// collected during validation.
333  ///
334  /// Prim and Schema type validators will be run on all \p timeCodes.
335  /// If \p timeCodes is empty, then no validation will be performed.
336  ///
337  /// Note that non-time dependent validators will be run only once and time
338  /// dependent validators will be run at all the provided timeCodes.
339  ///
340  /// \sa UsdValidationContext::Validate(const std::vector<UsdPrim> &prims,
341  /// UsdValidationTimeRange timeRange) const
344  const std::vector<UsdPrim> &prims,
345  const std::vector<UsdTimeCode> &timeCodes) const;
346 
347  /// Run validation on the given valid \p prims by executing the selected
348  /// validators for this UsdValidationContext; Returns a vector of errors
349  /// collected during validation.
350  ///
351  /// Prim and Schema type validators will be run on all \p timeCodes.
352  /// If \p timeCodes is empty, then no validation will be performed.
353  ///
354  /// Note that non-time dependent validators will be run only once and time
355  /// dependent validators will be run at all the provided timeCodes.
356  ///
357  /// \sa UsdValidationContext::Validate(const UsdPrimRange &prims,
358  /// UsdValidationTimeRange timeRange) const
361  const UsdPrimRange &prims,
362  const std::vector<UsdTimeCode> &timeCodes) const;
363 
364 private:
365  // helper to initialize UsdValidationContext, given a vector of metadata
366  // and a flag to include all ancestors.
367  void _InitializeFromValidatorMetadata(
368  const UsdValidationValidatorMetadataVector &metadata,
369  bool includeAllAncestors);
370 
371  // Distribute the validators into different groups based on the type of
372  // validation to be performed. This method distributes the selected
373  // validators into _layerValidators, _stageValidators, _primValidators and
374  // _schemaTypeValidators.
375  void _DistributeValidators(
376  const std::vector<const UsdValidationValidator *> &validators);
377 
378  // Helper enum to specify the state of time dependency for validation.
379  // This is used to determine if context need to run just time dependent,
380  // just non-time dependent or all validators.
381  enum class _TimeDependencyState {
384  All
385  };
386 
387  // Private helper functions to validate layers, stages and prims.
388  void _ValidateLayer(WorkDispatcher &dispatcher, const SdfLayerHandle &layer,
389  UsdValidationErrorVector *errors,
390  std::mutex *errorsMutex) const;
391 
392  // Helper function to validate a stage.
393  // - Layer Validators for all used layers in the stage
394  // - Stage Validators for the stage
395  // - Prim Validators for all prims in the stage, using the predicate
396  // to traverse the prims on the stage.
397  //
398  // Depending on whether an explicit timeRange is provided or a vector
399  // of timeCodes are provided, this function will do the following:
400  // - if timeRange is provided, it uses that to validate the stage and
401  // its prims using the predicate.
402  // - if timeCodes are provided:
403  // - Run all non-time dependent validators once.
404  // - Run all time dependent validators for all timeCodes.
405  void _ValidateStage(WorkDispatcher &dispatcher,
406  const UsdStagePtr &stage,
407  UsdValidationErrorVector *errors,
408  std::mutex *errorsMutex,
409  const Usd_PrimFlagsPredicate &predicate,
410  const std::variant<UsdValidationTimeRange,
411  std::vector<UsdTimeCode>> &times) const;
412 
413  // Helper function to validate prims. Generalized for UsdPrimRange and
414  // vector of UsdPrims.
415  template <typename T>
416  void _ValidatePrims(
417  WorkDispatcher &dispatcher, const T &prims,
418  UsdValidationErrorVector *errors, std::mutex *errorsMutex,
419  UsdValidationTimeRange timeRange,
420  _TimeDependencyState timeDependencyState =
422 
423  // Helper function to run _ValidatePrims within a scoped dispatcher.
424  // Templated to handle both PrimRange and vector of UsdPrims.
425  // Depending on whether an explicit timeRange is provided or a vector
426  // of timeCodes are provided, this function will do the following:
427  // - if timeRange is provided, it uses that to validate the prims.
428  // - if timeCodes are provided:
429  // - Run all non-time dependent validators once.
430  // - Run all time dependent validators for all timeCodes.
431  template <typename T>
432  void _RunValidatePrims(
433  const T &prims, UsdValidationErrorVector *errors,
434  std::mutex *errorsMutex,
435  const std::variant<UsdValidationTimeRange,
436  std::vector<UsdTimeCode>> &times) const;
437 
438  // Validators catering to a specific schemaType
439  using _SchemaTypeValidatorPair
440  = std::pair<TfToken, std::vector<const UsdValidationValidator *>>;
441  using _SchemaTypeValidatorPairVector
442  = std::vector<_SchemaTypeValidatorPair>;
443 
444  // Vectors of selected sets of validators, which will be run for this
445  // UsdValidationContext. Validation tasks will be enqueued for each of these
446  // validators on a given layer / stage or prims (traversed or explicitly
447  // specified).
448  std::vector<const UsdValidationValidator *> _layerValidators;
449  std::vector<const UsdValidationValidator *> _stageValidators;
450  std::vector<const UsdValidationValidator *> _primValidators;
451 
452  // validators here will be used to validate prims based on their schema
453  // types, such that:
454  // - For every typed schemaType found in here, prim being validated will be
455  // checked if it satisfies the IsA<schemaType> and validation task will be
456  // enqueued.
457  // - For every applied schemaType found in here, prim's appliedAPISchemas
458  // will be checked and if found, validation task will be enqueued for the
459  // prim.
460  _SchemaTypeValidatorPairVector _schemaTypeValidators;
461 };
462 
464 
465 #endif // PXR_USD_VALIDATION_USD_VALIDATION_CONTEXT_H
std::vector< UsdValidationValidatorMetadata > UsdValidationValidatorMetadataVector
Definition: validator.h:91
GLenum GLuint GLint GLint layer
Definition: glcorearb.h:1299
#define USDVALIDATION_API
Definition: api.h:25
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:440
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
USDVALIDATION_API UsdValidationErrorVector Validate(const SdfLayerHandle &layer) const
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
Definition: type.h:47
std::vector< UsdValidationError > UsdValidationErrorVector
Definition: validator.h:28
USDVALIDATION_API UsdValidationContext(const TfTokenVector &keywords, bool includeAllAncestors=true)