1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 //    names, trademarks, service marks, or product names of the Licensor
11 //    and its affiliates, except as required to comply with Section 4(c) of
12 //    the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 //     http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_USD_SDF_SCHEMA_H
25 #define PXR_USD_SDF_SCHEMA_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/usd/sdf/api.h"
29 #include "pxr/usd/sdf/allowed.h"
30 #include "pxr/usd/sdf/types.h"
31 #include "pxr/usd/sdf/valueTypeName.h"
32 
33 #include "pxr/base/plug/notice.h"
34 #include "pxr/base/tf/hash.h"
35 #include "pxr/base/tf/hashmap.h"
36 #include "pxr/base/tf/singleton.h"
37 #include "pxr/base/tf/staticTokens.h"
38 #include "pxr/base/tf/token.h"
39 #include "pxr/base/tf/type.h"
40 #include "pxr/base/tf/weakBase.h"
41 #include "pxr/base/vt/value.h"
42 
43 #include <memory>
44 #include <string>
45 #include <vector>
46 
47 PXR_NAMESPACE_OPEN_SCOPE
48 
49 class JsValue;
50 class SdfPath;
51 class SdfPayload;
52 class SdfReference;
53 class Sdf_ValueTypeRegistry;
54 
55 TF_DECLARE_WEAK_PTRS(PlugPlugin);
56 
57 /// \class SdfSchemaBase
58 ///
59 /// Generic class that provides information about scene description fields
60 /// but doesn't actually provide any fields.
61 ///
62 class SdfSchemaBase : public TfWeakBase, public boost::noncopyable {
63 
64 protected:
65     class _SpecDefiner;
66 
67 public:
68     /// \class FieldDefinition
69     ///
70     /// Class defining various attributes for a field.
71     ///
72     class FieldDefinition {
73     public:
74         FieldDefinition(
75             const SdfSchemaBase& schema,
76             const TfToken& name,
77             const VtValue& fallbackValue);
78 
79         typedef std::vector< std::pair<TfToken, JsValue> > InfoVec;
80 
81         SDF_API const TfToken& GetName() const;
82         SDF_API const VtValue& GetFallbackValue() const;
83         SDF_API const InfoVec& GetInfo() const;
84 
85         SDF_API bool IsPlugin() const;
86         SDF_API bool IsReadOnly() const;
87         SDF_API bool HoldsChildren() const;
88 
89         /// Validation functions that return true if a given value passes
90         /// the registered validator or if no validator has been set.
91         /// @{
92 
93         template <class T>
IsValidValue(const T & value)94         SdfAllowed IsValidValue(const T& value) const
95         {
96             return (_valueValidator ?
97                     _valueValidator(_schema, VtValue(value)) :
98                     SdfAllowed(true));
99         }
100 
101         template <class T>
IsValidListValue(const T & value)102         SdfAllowed IsValidListValue(const T& value) const
103         {
104             return (_listValueValidator ?
105                     _listValueValidator(_schema, VtValue(value)) :
106                     SdfAllowed(true));
107         }
108 
109         template <class T>
IsValidMapKey(const T & value)110         SdfAllowed IsValidMapKey(const T& value) const
111         {
112             return (_mapKeyValidator ?
113                     _mapKeyValidator(_schema, VtValue(value)) :
114                     SdfAllowed(true));
115         }
116 
117         template <class T>
IsValidMapValue(const T & value)118         SdfAllowed IsValidMapValue(const T& value) const
119         {
120             return (_mapValueValidator ?
121                     _mapValueValidator(_schema, VtValue(value)) :
122                     SdfAllowed(true));
123         }
124 
125         /// @}
126 
127         /// Functions for setting field attributes during registration.
128         /// @{
129 
130         FieldDefinition& FallbackValue(const VtValue& v);
131 
132         FieldDefinition& Plugin();
133         FieldDefinition& Children();
134         FieldDefinition& ReadOnly();
135         FieldDefinition& AddInfo(const TfToken& tok, const JsValue& val);
136 
137         using Validator =
138             SdfAllowed (*) (const SdfSchemaBase&, const VtValue&);
139         FieldDefinition& ValueValidator(Validator v);
140         FieldDefinition& ListValueValidator(Validator v);
141         FieldDefinition& MapKeyValidator(Validator v);
142         FieldDefinition& MapValueValidator(Validator v);
143 
144         /// @}
145 
146     private:
147         const SdfSchemaBase& _schema;
148         TfToken _name;
149         VtValue _fallbackValue;
150         InfoVec _info;
151 
152         bool _isPlugin;
153         bool _isReadOnly;
154         bool _holdsChildren;
155 
156         Validator _valueValidator;
157         Validator _listValueValidator;
158         Validator _mapKeyValidator;
159         Validator _mapValueValidator;
160     };
161 
162     // Structure containing information about a field as it pertains to the
163     // spec this object defines.
164     struct _FieldInfo {
_FieldInfo_FieldInfo165         _FieldInfo(): required(false), metadata(false) { }
166         bool required;
167         bool metadata;
168         TfToken metadataDisplayGroup;
169     };
170 
171     class SpecDefinition;
172 
173     /// \class SpecDefinition
174     ///
175     /// Class representing fields and other information for a spec type.
176     ///
177     class SpecDefinition {
178     public:
179         /// Returns all fields for this spec.
180         SDF_API TfTokenVector GetFields() const;
181 
182         /// Returns all value fields marked as required for this spec.
GetRequiredFields()183         TfTokenVector const &GetRequiredFields() const {
184             return _requiredFields;
185         }
186 
187         /// Returns all value fields marked as metadata for this spec.
188         SDF_API TfTokenVector GetMetadataFields() const;
189 
190         /// Returns whether the given field is valid for this spec.
191         SDF_API bool IsValidField(const TfToken& name) const;
192 
193         /// Returns whether the given field is metadata for this spec.
194         SDF_API bool IsMetadataField(const TfToken& name) const;
195 
196         /// Returns the display group for this metadata field.  Returns the
197         /// empty token if this field is not a metadata field or if this
198         /// metadata field has no display group.
199         SDF_API
200         TfToken GetMetadataFieldDisplayGroup(const TfToken& name) const;
201 
202         /// Returns whether the given field is required for this spec.
203         SDF_API bool IsRequiredField(const TfToken& name) const;
204 
205 
206     private:
207         typedef TfHashMap<TfToken, _FieldInfo, TfToken::HashFunctor>
208             _FieldMap;
209         _FieldMap _fields;
210 
211         // A separate vector of required field names from _fields.  Access to
212         // these is in a hot path, so we cache them separately.
213         TfTokenVector _requiredFields;
214 
215     private:
216         friend class _SpecDefiner;
217         void _AddField(const TfToken& name, const _FieldInfo& fieldInfo);
218     };
219 
220     /// Returns the field definition for the given field.
221     /// Returns NULL if no definition exists for given field.
222     SDF_API
223     const FieldDefinition* GetFieldDefinition(const TfToken &fieldKey) const;
224 
225     /// Returns the spec definition for the given spec type.
226     /// Returns NULL if no definition exists for the given spec type.
GetSpecDefinition(SdfSpecType specType)227     inline const SpecDefinition* GetSpecDefinition(SdfSpecType specType) const {
228         return _specDefinitions[specType].second ?
229             &_specDefinitions[specType].first : nullptr;
230     }
231 
232     /// Convenience functions for accessing specific field information.
233     /// @{
234 
235     /// Return whether the specified field has been registered. Also
236     /// optionally return the fallback value.
237     SDF_API
238     bool IsRegistered(const TfToken &fieldKey, VtValue *fallback=NULL) const;
239 
240     /// Returns whether the given field is a 'children' field -- that is, it
241     /// indexes certain children beneath the owning spec.
242     SDF_API
243     bool HoldsChildren(const TfToken &fieldKey) const;
244 
245     /// Return the fallback value for the specified \p fieldKey or the
246     /// empty value if \p fieldKey is not registered.
247     SDF_API
248     const VtValue& GetFallback(const TfToken &fieldKey) const;
249 
250     /// Coerce \p value to the correct type for the specified field.
251     SDF_API
252     VtValue CastToTypeOf(const TfToken &fieldKey, const VtValue &value) const;
253 
254     /// Return whether the given field is valid for the given spec type.
255     SDF_API
256     bool IsValidFieldForSpec(const TfToken &fieldKey, SdfSpecType specType) const;
257 
258     /// Returns all fields registered for the given spec type.
259     SDF_API TfTokenVector GetFields(SdfSpecType specType) const;
260 
261     /// Returns all metadata fields registered for the given spec type.
262     SDF_API TfTokenVector GetMetadataFields(SdfSpecType specType) const;
263 
264     /// Return the metadata field display group for metadata \a metadataField on
265     /// \a specType.  Return the empty token if \a metadataField is not a
266     /// metadata field, or if it has no display group.
267     SDF_API
268     TfToken GetMetadataFieldDisplayGroup(SdfSpecType specType,
269                                          TfToken const &metadataField) const;
270 
271     /// Returns all required fields registered for the given spec type.
272     SDF_API const TfTokenVector &GetRequiredFields(SdfSpecType specType) const;
273 
274     /// Return true if \p fieldName is a required field name for at least one
275     /// spec type, return false otherwise.  The main use of this function is to
276     /// quickly rule out field names that aren't required (and thus don't need
277     /// special handling).
IsRequiredFieldName(const TfToken & fieldName)278     inline bool IsRequiredFieldName(const TfToken &fieldName) const {
279         for (size_t i = 0; i != _requiredFieldNames.size(); ++i) {
280             if (_requiredFieldNames[i] == fieldName)
281                 return true;
282         }
283         return false;
284     }
285 
286     /// @}
287 
288     /// Specific validation functions for various fields. These are internally
289     /// registered as validators for the associated field, but can also be
290     /// used directly.
291     /// @{
292 
293     static SdfAllowed IsValidAttributeConnectionPath(const SdfPath& path);
294     static SdfAllowed IsValidIdentifier(const std::string& name);
295     static SdfAllowed IsValidNamespacedIdentifier(const std::string& name);
296     static SdfAllowed IsValidInheritPath(const SdfPath& path);
297     static SdfAllowed IsValidPayload(const SdfPayload& payload);
298     static SdfAllowed IsValidReference(const SdfReference& ref);
299     static SdfAllowed IsValidRelationshipTargetPath(const SdfPath& path);
300     static SdfAllowed IsValidRelocatesPath(const SdfPath& path);
301     static SdfAllowed IsValidSpecializesPath(const SdfPath& path);
302     static SdfAllowed IsValidSubLayer(const std::string& sublayer);
303     static SdfAllowed IsValidVariantIdentifier(const std::string& name);
304 
305     /// @}
306 
307     /// Scene description value types
308     /// @{
309 
310     /// Given a value, check if it is a valid value type.
311     /// This function only checks that the type of the value is valid
312     /// for this schema. It does not imply that the value is valid for
313     /// a particular field -- the field's validation function must be
314     /// used for that.
315     SDF_API
316     SdfAllowed IsValidValue(const VtValue& value) const;
317 
318     /// Returns all registered type names.
319     SDF_API
320     std::vector<SdfValueTypeName> GetAllTypes() const;
321 
322     /// Return the type name object for the given type name token.
323     SDF_API
324     SdfValueTypeName FindType(const TfToken& typeName) const;
325     /// \overload
326     SDF_API
327     SdfValueTypeName FindType(const char *typeName) const;
328     /// \overload
329     SDF_API
330     SdfValueTypeName FindType(std::string const &typeName) const;
331 
332     /// Return the type name object for the given type and optional role.
333     SDF_API
334     SdfValueTypeName FindType(const TfType& type,
335                               const TfToken& role = TfToken()) const;
336 
337     /// Return the type name object for the value's type and optional role.
338     SDF_API
339     SdfValueTypeName FindType(const VtValue& value,
340                               const TfToken& role = TfToken()) const;
341 
342     /// Return the type name object for the given type name string if it
343     /// exists otherwise create a temporary type name object.  Clients
344     /// should not normally need to call this.
345     SDF_API
346     SdfValueTypeName FindOrCreateType(const TfToken& typeName) const;
347 
348     /// @}
349 
350 protected:
351     /// \class _SpecDefiner
352     ///
353     /// Class that defines fields for a spec type.
354     ///
355     class _SpecDefiner {
356     public:
357         /// Functions for setting spec attributes during registration
358         /// @{
359 
360         _SpecDefiner& Field(
361             const TfToken& name, bool required = false);
362         _SpecDefiner& MetadataField(
363             const TfToken& name, bool required = false);
364         _SpecDefiner& MetadataField(
365             const TfToken& name, const TfToken& displayGroup,
366             bool required = false);
367 
368         _SpecDefiner &CopyFrom(const SpecDefinition &other);
369 
370         /// @}
371     private:
372         friend class SdfSchemaBase;
_SpecDefiner(SdfSchemaBase * schema,SpecDefinition * definition)373         explicit _SpecDefiner(SdfSchemaBase *schema, SpecDefinition *definition)
374             : _schema(schema)
375             , _definition(definition)
376             {}
377         SdfSchemaBase *_schema;
378         SpecDefinition *_definition;
379     };
380 
381     /// A helper for registering value types.
382     class _ValueTypeRegistrar {
383     public:
384         explicit _ValueTypeRegistrar(Sdf_ValueTypeRegistry*);
385 
386         class Type
387         {
388         public:
389             ~Type();
390 
391             // Specify a type with the given name, default value, and default
392             // array value of VtArray<T>.
393             template <class T>
Type(const TfToken & name,const T & defaultValue)394             Type(const TfToken& name, const T& defaultValue)
395                 : Type(name, VtValue(defaultValue), VtValue(VtArray<T>()))
396             { }
397             template <class T>
Type(char const * name,const T & defaultValue)398             Type(char const *name, const T& defaultValue)
399                 : Type(TfToken(name),
400                        VtValue(defaultValue), VtValue(VtArray<T>()))
401             { }
402 
403             // Specify a type with the given name and underlying C++ type.
404             // No default value or array value will be registered.
405             Type(const TfToken& name, const TfType& type);
406 
407             // Set C++ type name string for this type. Defaults to type name
408             // from TfType.
409             Type& CPPTypeName(const std::string& cppTypeName);
410 
411             // Set shape for this type. Defaults to shapeless.
412             Type& Dimensions(const SdfTupleDimensions& dims);
413 
414             // Set default unit for this type. Defaults to dimensionless unit.
415             Type& DefaultUnit(TfEnum unit);
416 
417             // Set role for this type. Defaults to no role.
418             Type& Role(const TfToken& role);
419 
420             // Indicate that arrays of this type are not supported.
421             Type& NoArrays();
422 
423         private:
424             Type(const TfToken& name,
425                  const VtValue& defaultValue,
426                  const VtValue& defaultArrayValue);
427 
428             class _Impl;
429             std::unique_ptr<_Impl> _impl;
430 
431             friend class _ValueTypeRegistrar;
432         };
433 
434         /// Register a value type and its corresponding array value type.
435         void AddType(const Type& type);
436 
437     private:
438         Sdf_ValueTypeRegistry* _registry;
439     };
440 
441     SdfSchemaBase();
442 
443     /// Construct an SdfSchemaBase but does not populate it with standard
444     /// fields and types.
445     class EmptyTag {};
446     SdfSchemaBase(EmptyTag);
447 
448     virtual ~SdfSchemaBase();
449 
450     /// Creates and registers a new field named \p fieldKey with the fallback
451     /// value \p fallback. If \p plugin is specified, it indicates that this
452     /// field is not a built-in field from this schema, but rather a field
453     /// that was externally registered.
454     ///
455     /// It is a fatal error to call this function with a key that has already
456     /// been used for another field.
457     template <class T>
458     FieldDefinition& _RegisterField(
459         const TfToken &fieldKey, const T &fallback, bool plugin = false)
460     {
461         return _CreateField(fieldKey, VtValue(fallback), plugin);
462     }
463 
464     /// Registers the given spec \p type with this schema and return a
465     /// _SpecDefiner for specifying additional fields.
_Define(SdfSpecType type)466     _SpecDefiner _Define(SdfSpecType type) {
467         // Mark the definition as valid and return a pointer to it.
468         _specDefinitions[type].second = true;
469         return _SpecDefiner(this, &_specDefinitions[type].first);
470     }
471 
472     /// Returns a _SpecDefiner for the previously-defined spec \p type
473     /// for specifying additional fields.
474     _SpecDefiner _ExtendSpecDefinition(SdfSpecType specType);
475 
476     /// Registers the standard fields.
477     void _RegisterStandardFields();
478 
479     /// Registers plugin fields and sets up handling so that fields will
480     /// be added when additional plugins are registered.
481     void _RegisterPluginFields();
482 
483     /// Registers standard attribute value types.
484     void _RegisterStandardTypes();
485 
486     /// Registers legacy attribute value types.
487     void _RegisterLegacyTypes();
488 
489     /// Returns a type registrar.
490     _ValueTypeRegistrar _GetTypeRegistrar() const;
491 
492     /// Factory function for creating a default value for a metadata
493     /// field. The parameters are the value type name and default
494     /// value (if any) specified in the defining plugin.
495     typedef std::function<VtValue(const std::string&, const JsValue&)>
496         _DefaultValueFactoryFn;
497 
498     /// Registers all metadata fields specified in the given plugins
499     /// under the given metadata tag.
500     const std::vector<const SdfSchemaBase::FieldDefinition *>
501     _UpdateMetadataFromPlugins(const PlugPluginPtrVector& plugins,
502                                     const std::string& metadataTag =
503                                         std::string(),
504                                     const _DefaultValueFactoryFn& defFactory =
505                                         _DefaultValueFactoryFn());
506 
507 private:
508     friend class _SpecDefiner;
509 
510     void _OnDidRegisterPlugins(const PlugNotice::DidRegisterPlugins& n);
511 
512     // Return a _SpecDefiner for an existing spec definition, \p local.
_Define(SpecDefinition * local)513     _SpecDefiner _Define(SpecDefinition *local) {
514         return _SpecDefiner(this, local);
515     }
516 
517     void _AddRequiredFieldName(const TfToken &name);
518 
519     const SpecDefinition* _CheckAndGetSpecDefinition(SdfSpecType type) const;
520 
521     friend struct Sdf_SchemaFieldTypeRegistrar;
522     FieldDefinition& _CreateField(
523         const TfToken &fieldKey, const VtValue &fallback, bool plugin = false);
524 
525     template <class T>
_DoRegisterField(const TfToken & fieldKey,const T & fallback)526     FieldDefinition& _DoRegisterField(const TfToken &fieldKey, const T &fallback)
527     {
528         return _DoRegisterField(fieldKey, VtValue(fallback));
529     }
530 
531     FieldDefinition& _DoRegisterField(
532         const TfToken &fieldKey, const VtValue &fallback);
533 
534 private:
535     typedef TfHashMap<TfToken, SdfSchemaBase::FieldDefinition,
536                                  TfToken::HashFunctor>
537         _FieldDefinitionMap;
538     _FieldDefinitionMap _fieldDefinitions;
539 
540     // Pair of definition and flag indicating validity.
541     std::pair<SdfSchemaBase::SpecDefinition, bool>
542     _specDefinitions[SdfNumSpecTypes];
543 
544     std::unique_ptr<Sdf_ValueTypeRegistry> _valueTypeRegistry;
545     TfTokenVector _requiredFieldNames;
546 };
547 
548 /// \class SdfSchema
549 ///
550 /// Class that provides information about the various scene description
551 /// fields.
552 ///
553 class SdfSchema : public SdfSchemaBase {
554 public:
555     SDF_API
GetInstance()556     static const SdfSchema& GetInstance()
557     {
558         return TfSingleton<SdfSchema>::GetInstance();
559     }
560 
561 private:
562     friend class TfSingleton<SdfSchema>;
563     SdfSchema();
564     virtual ~SdfSchema();
565 };
566 
567 SDF_API_TEMPLATE_CLASS(TfSingleton<SdfSchema>);
568 
569 ///
570 /// The following fields are pre-registered by Sdf.
571 /// \showinitializer
572 #define SDF_FIELD_KEYS                                       \
573     ((Active, "active"))                                     \
574     ((AllowedTokens, "allowedTokens"))                       \
575     ((AssetInfo, "assetInfo"))                               \
576     ((ColorConfiguration, "colorConfiguration"))             \
577     ((ColorManagementSystem, "colorManagementSystem"))       \
578     ((ColorSpace, "colorSpace"))                             \
579     ((Comment, "comment"))                                   \
580     ((ConnectionPaths, "connectionPaths"))                   \
581     ((Custom, "custom"))                                     \
582     ((CustomData, "customData"))                             \
583     ((CustomLayerData, "customLayerData"))                   \
584     ((Default, "default"))                                   \
585     ((DefaultPrim, "defaultPrim"))                           \
586     ((DisplayGroup, "displayGroup"))                         \
587     ((DisplayGroupOrder, "displayGroupOrder"))               \
588     ((DisplayName, "displayName"))                           \
589     ((DisplayUnit, "displayUnit"))                           \
590     ((Documentation, "documentation"))                       \
591     ((EndTimeCode, "endTimeCode"))                           \
592     ((FramePrecision, "framePrecision"))                     \
593     ((FramesPerSecond, "framesPerSecond"))                   \
594     ((Hidden, "hidden"))                                     \
595     ((HasOwnedSubLayers, "hasOwnedSubLayers"))               \
596     ((InheritPaths, "inheritPaths"))                         \
597     ((Instanceable, "instanceable"))                         \
598     ((Kind, "kind"))                                         \
599     ((PrimOrder, "primOrder"))                               \
600     ((NoLoadHint, "noLoadHint"))                             \
601     ((Owner, "owner"))                                       \
602     ((Payload, "payload"))                                   \
603     ((Permission, "permission"))                             \
604     ((Prefix, "prefix"))                                     \
605     ((PrefixSubstitutions, "prefixSubstitutions"))           \
606     ((PropertyOrder, "propertyOrder"))                       \
607     ((References, "references"))                             \
608     ((Relocates, "relocates"))                               \
609     ((SessionOwner, "sessionOwner"))                         \
610     ((Specializes, "specializes"))                           \
611     ((Specifier, "specifier"))                               \
612     ((StartTimeCode, "startTimeCode"))                       \
613     ((SubLayers, "subLayers"))                               \
614     ((SubLayerOffsets, "subLayerOffsets"))                   \
615     ((Suffix, "suffix"))                                     \
616     ((SuffixSubstitutions, "suffixSubstitutions"))           \
617     ((SymmetricPeer, "symmetricPeer"))                       \
618     ((SymmetryArgs, "symmetryArgs"))                         \
619     ((SymmetryArguments, "symmetryArguments"))               \
620     ((SymmetryFunction, "symmetryFunction"))                 \
621     ((TargetPaths, "targetPaths"))                           \
622     ((TimeSamples, "timeSamples"))                           \
623     ((TimeCodesPerSecond, "timeCodesPerSecond"))             \
624     ((TypeName, "typeName"))                                 \
625     ((VariantSelection, "variantSelection"))                 \
626     ((Variability, "variability"))                           \
627     ((VariantSetNames, "variantSetNames"))                   \
628                                                              \
629     /* XXX: These fields should move into Sd. See bug 123508. */ \
630     ((EndFrame, "endFrame"))                                 \
631     ((StartFrame, "startFrame"))
632 
633 #define SDF_CHILDREN_KEYS                                    \
634     ((ConnectionChildren, "connectionChildren"))             \
635     ((ExpressionChildren, "expressionChildren"))             \
636     ((MapperArgChildren, "mapperArgChildren"))               \
637     ((MapperChildren, "mapperChildren"))                     \
638     ((PrimChildren, "primChildren"))                         \
639     ((PropertyChildren, "properties"))                       \
640     ((RelationshipTargetChildren, "targetChildren"))         \
641     ((VariantChildren, "variantChildren"))                   \
642     ((VariantSetChildren, "variantSetChildren"))
643 
644 TF_DECLARE_PUBLIC_TOKENS(SdfFieldKeys, SDF_API, SDF_FIELD_KEYS);
645 TF_DECLARE_PUBLIC_TOKENS(SdfChildrenKeys, SDF_API, SDF_CHILDREN_KEYS);
646 
647 PXR_NAMESPACE_CLOSE_SCOPE
648 
649 #endif // PXR_USD_SDF_SCHEMA_H
650