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 
25 #include "pxr/pxr.h"
26 #include "pxr/usd/sdf/schema.h"
27 #include "pxr/usd/sdf/layer.h"
28 #include "pxr/usd/sdf/layerOffset.h"
29 #include "pxr/usd/sdf/parserValueContext.h"
30 #include "pxr/usd/sdf/payload.h"
31 #include "pxr/usd/sdf/reference.h"
32 #include "pxr/usd/sdf/schemaTypeRegistration.h"
33 #include "pxr/usd/sdf/tokens.h"
34 #include "pxr/usd/sdf/types.h"
35 #include "pxr/usd/sdf/valueTypeRegistry.h"
36 
37 #include "pxr/base/plug/plugin.h"
38 #include "pxr/base/plug/registry.h"
39 #include "pxr/base/tf/diagnostic.h"
40 #include "pxr/base/tf/instantiateSingleton.h"
41 #include "pxr/base/trace/trace.h"
42 #include "pxr/base/vt/dictionary.h"
43 
44 #include <deque>
45 #include <map>
46 #include <set>
47 #include <vector>
48 
49 using std::map;
50 using std::set;
51 using std::string;
52 using std::vector;
53 
54 PXR_NAMESPACE_OPEN_SCOPE
55 
56 TF_DEFINE_PRIVATE_TOKENS(
57     _tokens,
58 
59     ((Default, "default"))
60     ((DisplayGroup,"displayGroup"))
61     ((Type,"type"))
62     ((AppliesTo,"appliesTo"))
63 );
64 
65 //
66 // SdfSchemaBase::FieldDefinition
67 //
68 
FieldDefinition(const SdfSchemaBase & schema,const TfToken & name,const VtValue & fallbackValue)69 SdfSchemaBase::FieldDefinition::FieldDefinition(
70     const SdfSchemaBase& schema,
71     const TfToken& name,
72     const VtValue& fallbackValue)
73     : _schema(schema),
74       _name(name),
75       _fallbackValue(fallbackValue),
76       _isPlugin(false),
77       _isReadOnly(false),
78       _holdsChildren(false),
79       _valueValidator(nullptr),
80       _listValueValidator(nullptr),
81       _mapKeyValidator(nullptr),
82       _mapValueValidator(nullptr)
83 {
84 }
85 
86 const TfToken&
GetName() const87 SdfSchemaBase::FieldDefinition::GetName() const
88 {
89     return _name;
90 }
91 
92 const VtValue&
GetFallbackValue() const93 SdfSchemaBase::FieldDefinition::GetFallbackValue() const
94 {
95     return _fallbackValue;
96 }
97 
98 const SdfSchemaBase::FieldDefinition::InfoVec&
GetInfo() const99 SdfSchemaBase::FieldDefinition::GetInfo() const {
100     return _info;
101 }
102 
103 bool
IsPlugin() const104 SdfSchemaBase::FieldDefinition::IsPlugin() const
105 {
106     return _isPlugin;
107 }
108 
109 bool
IsReadOnly() const110 SdfSchemaBase::FieldDefinition::IsReadOnly() const
111 {
112     return _isReadOnly;
113 }
114 
115 bool
HoldsChildren() const116 SdfSchemaBase::FieldDefinition::HoldsChildren() const
117 {
118     return _holdsChildren;
119 }
120 
121 SdfSchemaBase::FieldDefinition&
FallbackValue(const VtValue & v)122 SdfSchemaBase::FieldDefinition::FallbackValue(const VtValue& v)
123 {
124     _fallbackValue = v;
125     return *this;
126 }
127 
128 SdfSchemaBase::FieldDefinition&
Plugin()129 SdfSchemaBase::FieldDefinition::Plugin()
130 {
131     _isPlugin = true;
132     return *this;
133 }
134 
135 SdfSchemaBase::FieldDefinition&
ReadOnly()136 SdfSchemaBase::FieldDefinition::ReadOnly()
137 {
138     _isReadOnly = true;
139     return *this;
140 }
141 
142 SdfSchemaBase::FieldDefinition&
Children()143 SdfSchemaBase::FieldDefinition::Children()
144 {
145     _holdsChildren = true;
146     _isReadOnly = true;
147     return *this;
148 }
149 
150 SdfSchemaBase::FieldDefinition&
AddInfo(const TfToken & tok,const JsValue & val)151 SdfSchemaBase::FieldDefinition::AddInfo(const TfToken& tok, const JsValue& val) {
152     _info.push_back(std::make_pair(tok, val));
153     return *this;
154 }
155 
156 SdfSchemaBase::FieldDefinition&
ValueValidator(Validator v)157 SdfSchemaBase::FieldDefinition::ValueValidator(Validator v)
158 {
159     _valueValidator = v;
160     return *this;
161 }
162 
163 SdfSchemaBase::FieldDefinition&
ListValueValidator(Validator v)164 SdfSchemaBase::FieldDefinition::ListValueValidator(Validator v)
165 {
166     _listValueValidator = v;
167     return *this;
168 }
169 
170 SdfSchemaBase::FieldDefinition&
MapKeyValidator(Validator v)171 SdfSchemaBase::FieldDefinition::MapKeyValidator(Validator v)
172 {
173     _mapKeyValidator = v;
174     return *this;
175 }
176 
177 SdfSchemaBase::FieldDefinition&
MapValueValidator(Validator v)178 SdfSchemaBase::FieldDefinition::MapValueValidator(Validator v)
179 {
180     _mapValueValidator = v;
181     return *this;
182 }
183 
184 //
185 // SdfSchemaBase::SpecDefinition
186 //
187 
188 TfTokenVector
GetFields() const189 SdfSchemaBase::SpecDefinition::GetFields() const
190 {
191     TRACE_FUNCTION();
192 
193     TfTokenVector rval(_fields.size());
194     TfToken *cur = rval.data();
195     for (auto const &p: _fields) {
196         *cur++ = p.first;
197     }
198     return rval;
199 }
200 
201 TfTokenVector
GetMetadataFields() const202 SdfSchemaBase::SpecDefinition::GetMetadataFields() const
203 {
204     TRACE_FUNCTION();
205 
206     TfTokenVector rval;
207     TF_FOR_ALL(field, _fields) {
208         if (field->second.metadata) {
209             rval.push_back(field->first);
210         }
211     }
212 
213     return rval;
214 }
215 
216 bool
IsMetadataField(const TfToken & name) const217 SdfSchemaBase::SpecDefinition::IsMetadataField(const TfToken& name) const
218 {
219     if (const _FieldInfo* fieldInfo = TfMapLookupPtr(_fields, name)) {
220         return fieldInfo->metadata;
221     }
222     return false;
223 }
224 
225 TfToken
226 SdfSchemaBase::SpecDefinition
GetMetadataFieldDisplayGroup(const TfToken & name) const227 ::GetMetadataFieldDisplayGroup(const TfToken& name) const
228 {
229     if (const _FieldInfo* fieldInfo = TfMapLookupPtr(_fields, name)) {
230         return fieldInfo->metadata ?
231             fieldInfo->metadataDisplayGroup : TfToken();
232     }
233     return TfToken();
234 }
235 
236 bool
IsRequiredField(const TfToken & name) const237 SdfSchemaBase::SpecDefinition::IsRequiredField(const TfToken& name) const
238 {
239     if (const _FieldInfo* fieldInfo = TfMapLookupPtr(_fields, name)) {
240         return fieldInfo->required;
241     }
242     return false;
243 }
244 
245 bool
IsValidField(const TfToken & name) const246 SdfSchemaBase::SpecDefinition::IsValidField(const TfToken& name) const
247 {
248     return _fields.find(name) != _fields.end();
249 }
250 
251 SdfSchemaBase::_SpecDefiner&
MetadataField(const TfToken & name,bool required)252 SdfSchemaBase::_SpecDefiner::MetadataField(const TfToken& name, bool required)
253 {
254     return MetadataField(name, TfToken(), required);
255 }
256 
257 SdfSchemaBase::_SpecDefiner&
MetadataField(const TfToken & name,const TfToken & displayGroup,bool required)258 SdfSchemaBase::_SpecDefiner::MetadataField(const TfToken& name,
259                                       const TfToken& displayGroup,
260                                       bool required)
261 {
262     _FieldInfo fieldInfo;
263     fieldInfo.metadata = true;
264     fieldInfo.metadataDisplayGroup = displayGroup;
265     fieldInfo.required = required;
266 
267     _definition->_AddField(name, fieldInfo);
268     if (required)
269         _schema->_AddRequiredFieldName(name);
270     return *this;
271 }
272 
273 SdfSchemaBase::_SpecDefiner&
Field(const TfToken & name,bool required)274 SdfSchemaBase::_SpecDefiner::Field(const TfToken& name, bool required)
275 {
276     _FieldInfo fieldInfo;
277     fieldInfo.required = required;
278 
279     _definition->_AddField(name, fieldInfo);
280     if (required)
281         _schema->_AddRequiredFieldName(name);
282     return *this;
283 }
284 
285 void
_AddField(const TfToken & name,const _FieldInfo & fieldInfo)286 SdfSchemaBase::SpecDefinition::_AddField(
287     const TfToken& name, const _FieldInfo& fieldInfo)
288 {
289     std::pair<_FieldMap::iterator, bool> insertStatus =
290         _fields.insert(std::make_pair(name, fieldInfo));
291     if (!insertStatus.second) {
292         TF_CODING_ERROR("Duplicate registration for field '%s'",
293                         name.GetText());
294         return;
295     }
296     if (fieldInfo.required) {
297         _requiredFields.insert(
298             std::lower_bound(_requiredFields.begin(),
299                              _requiredFields.end(), name), name);
300     }
301 }
302 
303 SdfSchemaBase::_SpecDefiner &
CopyFrom(const SpecDefinition & other)304 SdfSchemaBase::_SpecDefiner::CopyFrom(const SpecDefinition &other)
305 {
306     *_definition = other;
307     return *this;
308 }
309 
310 
311 //
312 // Validation helpers
313 //
314 
315 static
316 SdfAllowed
_ValidateFramesPerSecond(const SdfSchemaBase &,const VtValue & value)317 _ValidateFramesPerSecond(const SdfSchemaBase&, const VtValue& value)
318 {
319     if (!value.IsHolding<double>()) {
320         return SdfAllowed("Expected value of type double");
321     }
322 
323     return SdfAllowed(value.Get<double>() > 0.0,
324                      "Value must be greater than 0");
325 }
326 
327 static SdfAllowed
_ValidateIsString(const SdfSchemaBase &,const VtValue & value)328 _ValidateIsString(const SdfSchemaBase&, const VtValue& value)
329 {
330     if (!value.IsHolding<std::string>()) {
331         return SdfAllowed("Expected value of type string");
332     }
333     return true;
334 }
335 
336 static SdfAllowed
_ValidateIsNonEmptyString(const SdfSchemaBase & schema,const VtValue & value)337 _ValidateIsNonEmptyString(const SdfSchemaBase& schema, const VtValue& value)
338 {
339     SdfAllowed result = _ValidateIsString(schema, value);
340     if (result && value.Get<std::string>().empty()) {
341         result = SdfAllowed("Expected non-empty string");
342     }
343     return result;
344 }
345 
346 static SdfAllowed
_ValidateIdentifierToken(const SdfSchemaBase &,const VtValue & value)347 _ValidateIdentifierToken(const SdfSchemaBase&, const VtValue& value)
348 {
349     if (!value.IsHolding<TfToken>()) {
350         return SdfAllowed("Expected value of type TfToken");
351     }
352     return SdfSchemaBase::IsValidIdentifier(value.Get<TfToken>());
353 }
354 
355 static SdfAllowed
_ValidateNamespacedIdentifierToken(const SdfSchemaBase &,const VtValue & value)356 _ValidateNamespacedIdentifierToken(const SdfSchemaBase&, const VtValue& value)
357 {
358     if (!value.IsHolding<TfToken>()) {
359         return SdfAllowed("Expected value of type TfToken");
360     }
361     return SdfSchemaBase::IsValidNamespacedIdentifier(value.Get<TfToken>());
362 }
363 
364 static SdfAllowed
_ValidateIsSceneDescriptionValue(const SdfSchemaBase & schema,const VtValue & value)365 _ValidateIsSceneDescriptionValue(const SdfSchemaBase& schema, const VtValue& value)
366 {
367     return schema.IsValidValue(value);
368 }
369 
370 #define SDF_VALIDATE_WRAPPER(name_, expectedType_)                      \
371 static SdfAllowed                                                       \
372 _Validate ## name_(const SdfSchemaBase& schema, const VtValue& value)   \
373 {                                                                       \
374     if (!value.IsHolding<expectedType_>()) {                            \
375         return SdfAllowed("Expected value of type " # expectedType_);   \
376     }                                                                   \
377     return SdfSchemaBase::IsValid ## name_(value.Get<expectedType_>()); \
378 }
379 
380 SDF_VALIDATE_WRAPPER(AttributeConnectionPath, SdfPath);
381 SDF_VALIDATE_WRAPPER(Identifier, std::string);
382 SDF_VALIDATE_WRAPPER(InheritPath, SdfPath);
383 SDF_VALIDATE_WRAPPER(Payload, SdfPayload);
384 SDF_VALIDATE_WRAPPER(Reference, SdfReference);
385 SDF_VALIDATE_WRAPPER(RelationshipTargetPath, SdfPath);
386 SDF_VALIDATE_WRAPPER(RelocatesPath, SdfPath);
387 SDF_VALIDATE_WRAPPER(SpecializesPath, SdfPath);
388 SDF_VALIDATE_WRAPPER(SubLayer, std::string);
389 SDF_VALIDATE_WRAPPER(VariantIdentifier, std::string);
390 
391 TF_DEFINE_PUBLIC_TOKENS(SdfChildrenKeys, SDF_CHILDREN_KEYS);
392 TF_DEFINE_PUBLIC_TOKENS(SdfFieldKeys, SDF_FIELD_KEYS);
393 
394 //
395 // Registration for built-in fields for various spec types.
396 //
397 
398 struct Sdf_SchemaFieldTypeRegistrar
399 {
400 public:
Sdf_SchemaFieldTypeRegistrarSdf_SchemaFieldTypeRegistrar401     Sdf_SchemaFieldTypeRegistrar(SdfSchemaBase* schema) : _schema(schema) { }
402 
403     template <class T>
RegisterFieldSdf_SchemaFieldTypeRegistrar404     void RegisterField(const TfToken& fieldName)
405     {
406         _schema->_CreateField(fieldName, VtValue(T()));
407     }
408 
409 private:
410     SdfSchemaBase* _schema;
411 };
412 
413 //
414 // Registration for built-in attribute value types.
415 //
416 
417 static void
_AddStandardTypesToRegistry(Sdf_ValueTypeRegistry * r)418 _AddStandardTypesToRegistry(Sdf_ValueTypeRegistry* r)
419 {
420     using T = Sdf_ValueTypeRegistry::Type;
421     const TfEnum& length  = SdfDefaultUnit(TfEnum(SdfLengthUnit(0)));
422     const TfToken& point  = SdfValueRoleNames->Point;
423     const TfToken& vector = SdfValueRoleNames->Vector;
424     const TfToken& normal = SdfValueRoleNames->Normal;
425     const TfToken& color  = SdfValueRoleNames->Color;
426     const TfToken& texCoord = SdfValueRoleNames->TextureCoordinate;
427 
428     // Make sure TfTypes are registered.
429     TfRegistryManager::GetInstance().SubscribeTo<TfType>();
430 
431     // Simple types.
432     r->AddType(T("bool",   bool()));
433     // XXX: We also need to fix the VT_INTEGRAL_BUILTIN_VALUE_TYPES
434     //       macro to use 'int8_t' if we add 'char'.
435     //r->AddType(T("char",   int8_t());
436     r->AddType(T("uchar",  uint8_t()).CPPTypeName("unsigned char"));
437     //r->AddType(T("short",  int16_t());
438     //r->AddType(T("ushort", uint16_t());
439     r->AddType(T("int",    int32_t()).CPPTypeName("int"));
440     r->AddType(T("uint",   uint32_t()).CPPTypeName("unsigned int"));
441     r->AddType(T("int64",  int64_t()).CPPTypeName("int64_t"));
442     r->AddType(T("uint64", uint64_t()).CPPTypeName("uint64_t"));
443     r->AddType(T("half",   GfHalf(0.0)).CPPTypeName("GfHalf"));
444     r->AddType(T("float",  float()));
445     r->AddType(T("double", double()));
446     r->AddType(T("timecode", SdfTimeCode()));
447     // TfType reports "string" as the typename for "std::string", but we want
448     // the fully-qualified name for documentation purposes.
449     r->AddType(T("string", std::string()).CPPTypeName("std::string"));
450     r->AddType(T("token",  TfToken()));
451     r->AddType(T("asset",  SdfAssetPath()));
452 
453     // Compound types.
454     r->AddType(T("double2",  GfVec2d(0.0)).Dimensions(2));
455     r->AddType(T("double3",  GfVec3d(0.0)).Dimensions(3));
456     r->AddType(T("double4",  GfVec4d(0.0)).Dimensions(4));
457     r->AddType(T("float2",   GfVec2f(0.0)).Dimensions(2));
458     r->AddType(T("float3",   GfVec3f(0.0)).Dimensions(3));
459     r->AddType(T("float4",   GfVec4f(0.0)).Dimensions(4));
460     r->AddType(T("half2",    GfVec2h(0.0)).Dimensions(2));
461     r->AddType(T("half3",    GfVec3h(0.0)).Dimensions(3));
462     r->AddType(T("half4",    GfVec4h(0.0)).Dimensions(4));
463     r->AddType(T("int2",     GfVec2i(0.0)).Dimensions(2));
464     r->AddType(T("int3",     GfVec3i(0.0)).Dimensions(3));
465     r->AddType(T("int4",     GfVec4i(0.0)).Dimensions(4));
466     r->AddType(T("point3h",  GfVec3h(0.0)).DefaultUnit(length).Role(point)
467                                          .Dimensions(3));
468     r->AddType(T("point3f",  GfVec3f(0.0)).DefaultUnit(length).Role(point)
469                                          .Dimensions(3));
470     r->AddType(T("point3d",  GfVec3d(0.0)).DefaultUnit(length).Role(point)
471                                          .Dimensions(3));
472     r->AddType(T("vector3h", GfVec3h(0.0)).DefaultUnit(length).Role(vector)
473                                          .Dimensions(3));
474     r->AddType(T("vector3f", GfVec3f(0.0)).DefaultUnit(length).Role(vector)
475                                          .Dimensions(3));
476     r->AddType(T("vector3d", GfVec3d(0.0)).DefaultUnit(length).Role(vector)
477                                          .Dimensions(3));
478     r->AddType(T("normal3h", GfVec3h(0.0)).DefaultUnit(length).Role(normal)
479                                          .Dimensions(3));
480     r->AddType(T("normal3f", GfVec3f(0.0)).DefaultUnit(length).Role(normal)
481                                          .Dimensions(3));
482     r->AddType(T("normal3d", GfVec3d(0.0)).DefaultUnit(length).Role(normal)
483                                          .Dimensions(3));
484     r->AddType(T("color3h",  GfVec3h(0.0)).Role(color).Dimensions(3));
485     r->AddType(T("color3f",  GfVec3f(0.0)).Role(color).Dimensions(3));
486     r->AddType(T("color3d",  GfVec3d(0.0)).Role(color).Dimensions(3));
487     r->AddType(T("color4h",  GfVec4h(0.0)).Role(color).Dimensions(4));
488     r->AddType(T("color4f",  GfVec4f(0.0)).Role(color).Dimensions(4));
489     r->AddType(T("color4d",  GfVec4d(0.0)).Role(color).Dimensions(4));
490     r->AddType(T("quath",    GfQuath(1.0)).Dimensions(4));
491     r->AddType(T("quatf",    GfQuatf(1.0)).Dimensions(4));
492     r->AddType(T("quatd",    GfQuatd(1.0)).Dimensions(4));
493     r->AddType(T("matrix2d", GfMatrix2d(1.0)).Dimensions({2, 2}));
494     r->AddType(T("matrix3d", GfMatrix3d(1.0)).Dimensions({3, 3}));
495     r->AddType(T("matrix4d", GfMatrix4d(1.0)).Dimensions({4, 4}));
496     r->AddType(T("frame4d",  GfMatrix4d(1.0)).Role(SdfValueRoleNames->Frame)
497                                             .Dimensions({4, 4}));
498     r->AddType(T("texCoord2f", GfVec2f(0.0)).Role(texCoord).Dimensions(2));
499     r->AddType(T("texCoord2d", GfVec2d(0.0)).Role(texCoord).Dimensions(2));
500     r->AddType(T("texCoord2h", GfVec2h(0.0)).Role(texCoord).Dimensions(2));
501     r->AddType(T("texCoord3f", GfVec3f(0.0)).Role(texCoord).Dimensions(3));
502     r->AddType(T("texCoord3d", GfVec3d(0.0)).Role(texCoord).Dimensions(3));
503     r->AddType(T("texCoord3h", GfVec3h(0.0)).Role(texCoord).Dimensions(3));
504 }
505 
506 static void
_AddLegacyTypesToRegistry(Sdf_ValueTypeRegistry * r)507 _AddLegacyTypesToRegistry(Sdf_ValueTypeRegistry* r)
508 {
509     using T = Sdf_ValueTypeRegistry::Type;
510     const TfEnum& length  = SdfDefaultUnit(TfEnum(SdfLengthUnit(0)));
511     const TfToken& point  = SdfValueRoleNames->Point;
512     const TfToken& vector = SdfValueRoleNames->Vector;
513     const TfToken& normal = SdfValueRoleNames->Normal;
514     const TfToken& color  = SdfValueRoleNames->Color;
515 
516     // XXX: Legacy types.  We can remove these when assets are
517     //      updated.  parserHelpers.cpp adds support for reading
518     //      old text Usd files but we also need support for binary
519     //      files.  We also need these for places we confuse Sdf
520     //      and Sd.
521     r->AddType(T("Vec2i",      GfVec2i(0.0)).Dimensions(2));
522     r->AddType(T("Vec2h",      GfVec2h(0.0)).Dimensions(2));
523     r->AddType(T("Vec2f",      GfVec2f(0.0)).Dimensions(2));
524     r->AddType(T("Vec2d",      GfVec2d(0.0)).Dimensions(2));
525     r->AddType(T("Vec3i",      GfVec3i(0.0)).Dimensions(3));
526     r->AddType(T("Vec3h",      GfVec3h(0.0)).Dimensions(3));
527     r->AddType(T("Vec3f",      GfVec3f(0.0)).Dimensions(3));
528     r->AddType(T("Vec3d",      GfVec3d(0.0)).Dimensions(3));
529     r->AddType(T("Vec4i",      GfVec4i(0.0)).Dimensions(4));
530     r->AddType(T("Vec4h",      GfVec4h(0.0)).Dimensions(4));
531     r->AddType(T("Vec4f",      GfVec4f(0.0)).Dimensions(4));
532     r->AddType(T("Vec4d",      GfVec4d(0.0)).Dimensions(4));
533     r->AddType(T("Point",      GfVec3d(0.0)).DefaultUnit(length).Role(point)
534                                            .Dimensions(3));
535     r->AddType(T("PointFloat", GfVec3f(0.0)).DefaultUnit(length).Role(point)
536                                            .Dimensions(3));
537     r->AddType(T("Normal",     GfVec3d(0.0)).DefaultUnit(length).Role(normal)
538                                            .Dimensions(3));
539     r->AddType(T("NormalFloat",GfVec3f(0.0)).DefaultUnit(length).Role(normal)
540                                            .Dimensions(3));
541     r->AddType(T("Vector",     GfVec3d(0.0)).DefaultUnit(length).Role(vector)
542                                            .Dimensions(3));
543     r->AddType(T("VectorFloat",GfVec3f(0.0)).DefaultUnit(length).Role(vector)
544                                            .Dimensions(3));
545     r->AddType(T("Color",      GfVec3d(0.0)).Role(color).Dimensions(3));
546     r->AddType(T("ColorFloat", GfVec3f(0.0)).Role(color).Dimensions(3));
547     r->AddType(T("Quath",      GfQuath(1.0)).Dimensions(4));
548     r->AddType(T("Quatf",      GfQuatf(1.0)).Dimensions(4));
549     r->AddType(T("Quatd",      GfQuatd(1.0)).Dimensions(4));
550     r->AddType(T("Matrix2d",   GfMatrix2d(1.0)).Dimensions({2, 2}));
551     r->AddType(T("Matrix3d",   GfMatrix3d(1.0)).Dimensions({3, 3}));
552     r->AddType(T("Matrix4d",   GfMatrix4d(1.0)).Dimensions({4, 4}));
553     r->AddType(T("Frame",      GfMatrix4d(1.0)).Role(SdfValueRoleNames->Frame)
554                                               .Dimensions({4, 4}));
555     r->AddType(T("Transform",  GfMatrix4d(1.0)).Role(SdfValueRoleNames->Transform)
556                                               .Dimensions({4, 4}));
557     r->AddType(T("PointIndex", int()).Role(SdfValueRoleNames->PointIndex));
558     r->AddType(T("EdgeIndex",  int()).Role(SdfValueRoleNames->EdgeIndex));
559     r->AddType(T("FaceIndex",  int()).Role(SdfValueRoleNames->FaceIndex));
560 }
561 
562 class SdfSchemaBase::_ValueTypeRegistrar::Type::_Impl
563 {
564 public:
_Impl(const TfToken & name,const VtValue & defaultValue,const VtValue & defaultArrayValue)565     _Impl(const TfToken& name,
566           const VtValue& defaultValue,
567           const VtValue& defaultArrayValue)
568         : type(name, defaultValue, defaultArrayValue)
569     { }
570 
_Impl(const TfToken & name,const TfType & type_)571     _Impl(const TfToken& name, const TfType& type_)
572         : type(name, type_)
573     { }
574 
575     Sdf_ValueTypeRegistry::Type type;
576 };
577 
Type(const TfToken & name,const VtValue & defaultValue,const VtValue & defaultArrayValue)578 SdfSchemaBase::_ValueTypeRegistrar::Type::Type(
579     const TfToken& name,
580     const VtValue& defaultValue,
581     const VtValue& defaultArrayValue)
582     : _impl(new _Impl(name, defaultValue, defaultArrayValue))
583 {
584 }
585 
Type(const TfToken & name,const TfType & type)586 SdfSchemaBase::_ValueTypeRegistrar::Type::Type(
587     const TfToken& name,
588     const TfType& type)
589     : _impl(new _Impl(name, type))
590 {
591 }
592 
593 SdfSchemaBase::_ValueTypeRegistrar::Type::~Type() = default;
594 
595 SdfSchemaBase::_ValueTypeRegistrar::Type&
CPPTypeName(const std::string & cppTypeName)596 SdfSchemaBase::_ValueTypeRegistrar::Type::CPPTypeName(
597     const std::string& cppTypeName)
598 {
599     _impl->type.CPPTypeName(cppTypeName);
600     return *this;
601 }
602 
603 SdfSchemaBase::_ValueTypeRegistrar::Type&
Dimensions(const SdfTupleDimensions & dims)604 SdfSchemaBase::_ValueTypeRegistrar::Type::Dimensions(
605     const SdfTupleDimensions& dims)
606 {
607     _impl->type.Dimensions(dims);
608     return *this;
609 }
610 
611 SdfSchemaBase::_ValueTypeRegistrar::Type&
DefaultUnit(TfEnum unit)612 SdfSchemaBase::_ValueTypeRegistrar::Type::DefaultUnit(TfEnum unit)
613 {
614     _impl->type.DefaultUnit(unit);
615     return *this;
616 }
617 
618 SdfSchemaBase::_ValueTypeRegistrar::Type&
Role(const TfToken & role)619 SdfSchemaBase::_ValueTypeRegistrar::Type::Role(const TfToken& role)
620 {
621     _impl->type.Role(role);
622     return *this;
623 }
624 
625 SdfSchemaBase::_ValueTypeRegistrar::Type&
NoArrays()626 SdfSchemaBase::_ValueTypeRegistrar::Type::NoArrays()
627 {
628     _impl->type.NoArrays();
629     return *this;
630 }
631 
_ValueTypeRegistrar(Sdf_ValueTypeRegistry * registry)632 SdfSchemaBase::_ValueTypeRegistrar::_ValueTypeRegistrar(
633     Sdf_ValueTypeRegistry* registry) :
634     _registry(registry)
635 {
636     // Do nothing
637 }
638 
639 void
AddType(const Type & type)640 SdfSchemaBase::_ValueTypeRegistrar::AddType(const Type& type)
641 {
642     _registry->AddType(type._impl->type);
643 }
644 
TF_REGISTRY_FUNCTION(TfType)645 TF_REGISTRY_FUNCTION(TfType)
646 {
647     TfType::Define<SdfSchemaBase>();
648 }
649 
SdfSchemaBase()650 SdfSchemaBase::SdfSchemaBase()
651     : _valueTypeRegistry(new Sdf_ValueTypeRegistry)
652 {
653     _RegisterStandardTypes();
654     _RegisterLegacyTypes();
655 
656     _RegisterStandardFields();
657     _RegisterPluginFields();
658 }
659 
SdfSchemaBase(EmptyTag)660 SdfSchemaBase::SdfSchemaBase(EmptyTag)
661     : _valueTypeRegistry(new Sdf_ValueTypeRegistry)
662 {
663 }
664 
~SdfSchemaBase()665 SdfSchemaBase::~SdfSchemaBase()
666 {
667     // Do nothing
668 }
669 
670 void
_RegisterStandardTypes()671 SdfSchemaBase::_RegisterStandardTypes()
672 {
673     _AddStandardTypesToRegistry(_valueTypeRegistry.get());
674 }
675 
676 void
_RegisterLegacyTypes()677 SdfSchemaBase::_RegisterLegacyTypes()
678 {
679     _AddLegacyTypesToRegistry(_valueTypeRegistry.get());
680 }
681 
682 void
_RegisterStandardFields()683 SdfSchemaBase::_RegisterStandardFields()
684 {
685     // Ensure that entries for all scene description fields
686     // are created with an appropriately-typed fallback value.
687     // Then register additional information for each field; doing so
688     // for a field that hasn't been created will cause a fatal error
689     // to be emitted.
690     //
691     // This ensures that the field registration stays in sync with
692     // the field types defined in SchemaTypeRegistration.h
693     Sdf_SchemaFieldTypeRegistrar r(this);
694     SdfRegisterFields(&r);
695 
696     // Regular Fields
697     _DoRegisterField(SdfFieldKeys->Active, true);
698     _DoRegisterField(SdfFieldKeys->AllowedTokens, VtTokenArray());
699     _DoRegisterField(SdfFieldKeys->AssetInfo, VtDictionary())
700         .MapKeyValidator(&_ValidateIdentifier)
701         .MapValueValidator(&_ValidateIsSceneDescriptionValue);
702     _DoRegisterField(SdfFieldKeys->TimeSamples, SdfTimeSampleMap());
703     _DoRegisterField(SdfFieldKeys->ColorConfiguration, SdfAssetPath());
704     _DoRegisterField(SdfFieldKeys->ColorManagementSystem, TfToken());
705     _DoRegisterField(SdfFieldKeys->ColorSpace, TfToken());
706     _DoRegisterField(SdfFieldKeys->Comment, "");
707 
708     // Connection paths are marked read-only because adding/removing
709     // connections requires adding/removing children specs, which we are
710     // disallowing via the Info API.
711     _DoRegisterField(SdfFieldKeys->ConnectionPaths, SdfPathListOp())
712         .ReadOnly()
713         .ListValueValidator(&_ValidateAttributeConnectionPath);
714 
715     _DoRegisterField(SdfFieldKeys->Custom, false);
716     _DoRegisterField(SdfFieldKeys->CustomData, VtDictionary())
717         .MapKeyValidator(&_ValidateIdentifier)
718         .MapValueValidator(&_ValidateIsSceneDescriptionValue);
719     _DoRegisterField(SdfFieldKeys->CustomLayerData, VtDictionary())
720         .MapKeyValidator(&_ValidateIdentifier)
721         .MapValueValidator(&_ValidateIsSceneDescriptionValue);
722     _DoRegisterField(SdfFieldKeys->Default, VtValue())
723         .ValueValidator(&_ValidateIsSceneDescriptionValue);
724     _DoRegisterField(SdfFieldKeys->DisplayGroup, "");
725     _DoRegisterField(SdfFieldKeys->DisplayGroupOrder, VtStringArray());
726     _DoRegisterField(SdfFieldKeys->DisplayName, "");
727     _DoRegisterField(SdfFieldKeys->DisplayUnit,
728                    TfEnum(SdfDimensionlessUnitDefault));
729     _DoRegisterField(SdfFieldKeys->Documentation, "");
730     _DoRegisterField(SdfFieldKeys->DefaultPrim, TfToken());
731     _DoRegisterField(SdfFieldKeys->EndFrame, 0.0);
732     _DoRegisterField(SdfFieldKeys->EndTimeCode, 0.0);
733     _DoRegisterField(SdfFieldKeys->FramePrecision, 3);
734     _DoRegisterField(SdfFieldKeys->FramesPerSecond, 24.0)
735         .ValueValidator(&_ValidateFramesPerSecond);
736     _DoRegisterField(SdfFieldKeys->Hidden, false);
737     _DoRegisterField(SdfFieldKeys->HasOwnedSubLayers, false);
738     _DoRegisterField(SdfFieldKeys->Instanceable, false);
739     _DoRegisterField(SdfFieldKeys->InheritPaths, SdfPathListOp())
740         .ListValueValidator(&_ValidateInheritPath);
741     _DoRegisterField(SdfFieldKeys->Kind, TfToken());
742     _DoRegisterField(SdfFieldKeys->Owner, "");
743     _DoRegisterField(SdfFieldKeys->PrimOrder, std::vector<TfToken>())
744         .ListValueValidator(&_ValidateIdentifierToken);
745     _DoRegisterField(SdfFieldKeys->NoLoadHint, false);
746     _DoRegisterField(SdfFieldKeys->Payload, SdfPayloadListOp())
747         .ListValueValidator(&_ValidatePayload);
748     _DoRegisterField(SdfFieldKeys->Permission, SdfPermissionPublic);
749     _DoRegisterField(SdfFieldKeys->Prefix, "");
750     _DoRegisterField(SdfFieldKeys->PrefixSubstitutions, VtDictionary())
751         .MapKeyValidator(&_ValidateIsNonEmptyString)
752         .MapValueValidator(&_ValidateIsString);
753     _DoRegisterField(SdfFieldKeys->PropertyOrder, std::vector<TfToken>())
754         .ListValueValidator(&_ValidateNamespacedIdentifierToken);
755     _DoRegisterField(SdfFieldKeys->References, SdfReferenceListOp())
756         .ListValueValidator(&_ValidateReference);
757     _DoRegisterField(SdfFieldKeys->SessionOwner, "");
758     _DoRegisterField(SdfFieldKeys->Specializes, SdfPathListOp())
759         .ListValueValidator(&_ValidateSpecializesPath);
760     _DoRegisterField(SdfFieldKeys->Suffix, "");
761     _DoRegisterField(SdfFieldKeys->SuffixSubstitutions, VtDictionary())
762         .MapKeyValidator(&_ValidateIsNonEmptyString)
763         .MapValueValidator(&_ValidateIsString);
764 
765     // See comment on SdfFieldKeys->ConnectionPaths for why this is read-only.
766     _DoRegisterField(SdfFieldKeys->TargetPaths,  SdfPathListOp())
767         .ReadOnly()
768         .ListValueValidator(&_ValidateRelationshipTargetPath);
769 
770     _DoRegisterField(SdfFieldKeys->Relocates, SdfRelocatesMap())
771         .MapKeyValidator(&_ValidateRelocatesPath)
772         .MapValueValidator(&_ValidateRelocatesPath);
773     _DoRegisterField(SdfFieldKeys->Specifier, SdfSpecifierOver);
774     _DoRegisterField(SdfFieldKeys->StartFrame, 0.0);
775     _DoRegisterField(SdfFieldKeys->StartTimeCode, 0.0);
776     _DoRegisterField(SdfFieldKeys->SubLayers, std::vector<std::string>())
777         .ListValueValidator(&_ValidateSubLayer);
778     _DoRegisterField(SdfFieldKeys->SubLayerOffsets, std::vector<SdfLayerOffset>());
779     _DoRegisterField(SdfFieldKeys->SymmetricPeer, "");
780     _DoRegisterField(SdfFieldKeys->SymmetryArgs, VtDictionary())
781         .MapKeyValidator(&_ValidateIdentifier)
782         .MapValueValidator(&_ValidateIsSceneDescriptionValue);
783     _DoRegisterField(SdfFieldKeys->SymmetryArguments, VtDictionary())
784         .MapKeyValidator(&_ValidateIdentifier)
785         .MapValueValidator(&_ValidateIsSceneDescriptionValue);
786     _DoRegisterField(SdfFieldKeys->SymmetryFunction, TfToken());
787     _DoRegisterField(SdfFieldKeys->TimeCodesPerSecond, 24.0);
788     _DoRegisterField(SdfFieldKeys->TypeName, TfToken());
789     _DoRegisterField(SdfFieldKeys->VariantSetNames, SdfStringListOp())
790         .ListValueValidator(&_ValidateIdentifier);
791     _DoRegisterField(SdfFieldKeys->VariantSelection, SdfVariantSelectionMap())
792         .MapValueValidator(&_ValidateVariantIdentifier);
793     _DoRegisterField(SdfFieldKeys->Variability, SdfVariabilityVarying);
794 
795     // Children fields.
796     _DoRegisterField(SdfChildrenKeys->ConnectionChildren, std::vector<SdfPath>())
797         .Children()
798         .ListValueValidator(&_ValidateAttributeConnectionPath);
799     _DoRegisterField(SdfChildrenKeys->ExpressionChildren, std::vector<TfToken>())
800         .Children();
801     _DoRegisterField(SdfChildrenKeys->MapperArgChildren, std::vector<TfToken>())
802         .Children()
803         .ListValueValidator(&_ValidateIdentifier);
804     _DoRegisterField(SdfChildrenKeys->MapperChildren, std::vector<SdfPath>())
805         .Children()
806         .ListValueValidator(&_ValidateAttributeConnectionPath);
807     _DoRegisterField(SdfChildrenKeys->PrimChildren, std::vector<TfToken>())
808         .Children()
809         .ListValueValidator(&_ValidateIdentifier);
810     _DoRegisterField(SdfChildrenKeys->PropertyChildren, std::vector<TfToken>())
811         .Children()
812         .ListValueValidator(&_ValidateIdentifier);
813     _DoRegisterField(SdfChildrenKeys->RelationshipTargetChildren,
814                    std::vector<SdfPath>())
815         .Children()
816         .ListValueValidator(&_ValidateRelationshipTargetPath);
817     _DoRegisterField(SdfChildrenKeys->VariantChildren, std::vector<TfToken>())
818         .Children()
819         .ListValueValidator(&_ValidateVariantIdentifier);
820     _DoRegisterField(SdfChildrenKeys->VariantSetChildren, std::vector<TfToken>())
821         .Children()
822         .ListValueValidator(&_ValidateIdentifier);
823 
824     //
825     // Spec definitions
826     //
827 
828     _Define(SdfSpecTypePseudoRoot)
829         .MetadataField(SdfFieldKeys->ColorConfiguration)
830         .MetadataField(SdfFieldKeys->ColorManagementSystem)
831         .Field(SdfFieldKeys->Comment)
832         .MetadataField(SdfFieldKeys->CustomLayerData)
833         .MetadataField(SdfFieldKeys->DefaultPrim)
834         .MetadataField(SdfFieldKeys->Documentation)
835         .MetadataField(SdfFieldKeys->EndTimeCode)
836         .MetadataField(SdfFieldKeys->FramesPerSecond)
837         .MetadataField(SdfFieldKeys->FramePrecision)
838         .MetadataField(SdfFieldKeys->HasOwnedSubLayers)
839         .MetadataField(SdfFieldKeys->Owner)
840         .MetadataField(SdfFieldKeys->SessionOwner)
841         .MetadataField(SdfFieldKeys->StartTimeCode)
842         .MetadataField(SdfFieldKeys->TimeCodesPerSecond)
843         .MetadataField(SdfFieldKeys->EndFrame)
844         .MetadataField(SdfFieldKeys->StartFrame)
845 
846         .Field(SdfChildrenKeys->PrimChildren)
847         .Field(SdfFieldKeys->PrimOrder)
848         .Field(SdfFieldKeys->SubLayers)
849         .Field(SdfFieldKeys->SubLayerOffsets);
850 
851     _Define(SdfSpecTypePrim)
852         .Field(SdfFieldKeys->Specifier, /* required = */ true)
853 
854         .Field(SdfFieldKeys->Comment)
855         .Field(SdfFieldKeys->InheritPaths)
856         .Field(SdfFieldKeys->Specializes)
857         .Field(SdfChildrenKeys->PrimChildren)
858         .Field(SdfFieldKeys->PrimOrder)
859         .Field(SdfChildrenKeys->PropertyChildren)
860         .Field(SdfFieldKeys->PropertyOrder)
861         .Field(SdfFieldKeys->References)
862         .Field(SdfFieldKeys->Relocates)
863         .Field(SdfFieldKeys->VariantSelection)
864         .Field(SdfChildrenKeys->VariantSetChildren)
865         .Field(SdfFieldKeys->VariantSetNames)
866 
867         .MetadataField(SdfFieldKeys->Active,
868                        SdfMetadataDisplayGroupTokens->core)
869         .MetadataField(SdfFieldKeys->AssetInfo,
870                        SdfMetadataDisplayGroupTokens->core)
871         .MetadataField(SdfFieldKeys->CustomData,
872                        SdfMetadataDisplayGroupTokens->core)
873         .MetadataField(SdfFieldKeys->DisplayGroupOrder,
874                        SdfMetadataDisplayGroupTokens->core)
875         .MetadataField(SdfFieldKeys->Documentation,
876                        SdfMetadataDisplayGroupTokens->core)
877         .MetadataField(SdfFieldKeys->Hidden,
878                        SdfMetadataDisplayGroupTokens->core)
879         .MetadataField(SdfFieldKeys->Instanceable,
880                        SdfMetadataDisplayGroupTokens->core)
881         .MetadataField(SdfFieldKeys->Kind,
882                        SdfMetadataDisplayGroupTokens->core)
883         .MetadataField(SdfFieldKeys->Payload,
884                        SdfMetadataDisplayGroupTokens->core)
885         .MetadataField(SdfFieldKeys->Permission,
886                        SdfMetadataDisplayGroupTokens->core)
887         .MetadataField(SdfFieldKeys->Prefix,
888                        SdfMetadataDisplayGroupTokens->core)
889         .MetadataField(SdfFieldKeys->PrefixSubstitutions,
890                        SdfMetadataDisplayGroupTokens->core)
891         .MetadataField(SdfFieldKeys->Suffix,
892                        SdfMetadataDisplayGroupTokens->core)
893         .MetadataField(SdfFieldKeys->SuffixSubstitutions,
894                        SdfMetadataDisplayGroupTokens->core)
895         .MetadataField(SdfFieldKeys->SymmetricPeer,
896                        SdfMetadataDisplayGroupTokens->symmetry)
897         .MetadataField(SdfFieldKeys->SymmetryArguments,
898                        SdfMetadataDisplayGroupTokens->symmetry)
899         .MetadataField(SdfFieldKeys->SymmetryFunction,
900                        SdfMetadataDisplayGroupTokens->symmetry)
901         .MetadataField(SdfFieldKeys->TypeName,
902                        SdfMetadataDisplayGroupTokens->core)
903         ;
904 
905     // The property spec definition will be used as the basis for the
906     // attribute and relationship spec definitions.
907     SpecDefinition property;
908     _Define(&property)
909         .Field(SdfFieldKeys->Custom,      /* required = */ true)
910         .Field(SdfFieldKeys->Variability, /* required = */ true)
911 
912         .Field(SdfFieldKeys->Comment)
913         .Field(SdfFieldKeys->Default)
914         .Field(SdfFieldKeys->TimeSamples)
915 
916         .MetadataField(SdfFieldKeys->AssetInfo,
917                        SdfMetadataDisplayGroupTokens->core)
918         .MetadataField(SdfFieldKeys->CustomData,
919                        SdfMetadataDisplayGroupTokens->core)
920         .MetadataField(SdfFieldKeys->DisplayGroup,
921                        SdfMetadataDisplayGroupTokens->core)
922         .MetadataField(SdfFieldKeys->DisplayName,
923                        SdfMetadataDisplayGroupTokens->core)
924         .MetadataField(SdfFieldKeys->Documentation,
925                        SdfMetadataDisplayGroupTokens->core)
926         .MetadataField(SdfFieldKeys->Hidden,
927                        SdfMetadataDisplayGroupTokens->core)
928         .MetadataField(SdfFieldKeys->Permission,
929                        SdfMetadataDisplayGroupTokens->core)
930         .MetadataField(SdfFieldKeys->Prefix,
931                        SdfMetadataDisplayGroupTokens->core)
932         .MetadataField(SdfFieldKeys->Suffix,
933                        SdfMetadataDisplayGroupTokens->core)
934         .MetadataField(SdfFieldKeys->SymmetricPeer,
935                        SdfMetadataDisplayGroupTokens->symmetry)
936         .MetadataField(SdfFieldKeys->SymmetryArguments,
937                        SdfMetadataDisplayGroupTokens->symmetry)
938         .MetadataField(SdfFieldKeys->SymmetryFunction,
939                        SdfMetadataDisplayGroupTokens->symmetry)
940         ;
941 
942     _Define(SdfSpecTypeAttribute)
943         .CopyFrom(property)
944         .Field(SdfFieldKeys->TypeName,                /* required = */ true)
945 
946         .Field(SdfChildrenKeys->ConnectionChildren)
947         .Field(SdfFieldKeys->ConnectionPaths)
948         .Field(SdfFieldKeys->DisplayUnit)
949         .MetadataField(SdfFieldKeys->AllowedTokens,
950                        SdfMetadataDisplayGroupTokens->core)
951         .MetadataField(SdfFieldKeys->ColorSpace,
952                        SdfMetadataDisplayGroupTokens->core)
953         ;
954 
955     _Define(SdfSpecTypeConnection);
956 
957     _Define(SdfSpecTypeRelationship)
958         .CopyFrom(property)
959         .Field(SdfChildrenKeys->RelationshipTargetChildren)
960         .Field(SdfFieldKeys->TargetPaths)
961 
962         .MetadataField(SdfFieldKeys->NoLoadHint,
963                        SdfMetadataDisplayGroupTokens->core);
964 
965     _Define(SdfSpecTypeRelationshipTarget);
966 
967     _Define(SdfSpecTypeVariantSet)
968         .Field(SdfChildrenKeys->VariantChildren);
969 
970     _Define(SdfSpecTypeVariant)
971         .CopyFrom(*GetSpecDefinition(SdfSpecTypePrim));
972 
973 }
974 
975 void
_RegisterPluginFields()976 SdfSchemaBase::_RegisterPluginFields()
977 {
978     // Update generic metadata fields from all currently-registered plugins.
979     // Set up notice handling so we'll check for new generic metadata as more
980     // plugins are registered.
981     _UpdateMetadataFromPlugins(PlugRegistry::GetInstance().GetAllPlugins());
982     TfNotice::Register(
983         TfCreateWeakPtr(this), &SdfSchemaBase::_OnDidRegisterPlugins);
984 }
985 
986 void
_OnDidRegisterPlugins(const PlugNotice::DidRegisterPlugins & n)987 SdfSchemaBase::_OnDidRegisterPlugins(const PlugNotice::DidRegisterPlugins& n)
988 {
989     _UpdateMetadataFromPlugins(n.GetNewPlugins());
990 }
991 
992 SdfSchemaBase::FieldDefinition&
_CreateField(const TfToken & key,const VtValue & value,bool plugin)993 SdfSchemaBase::_CreateField(const TfToken &key, const VtValue &value, bool plugin)
994 {
995     FieldDefinition def(*this, key, value);
996     if (plugin) {
997         def.Plugin();
998     }
999 
1000     const std::pair<_FieldDefinitionMap::iterator, bool> insertStatus =
1001         _fieldDefinitions.insert(std::make_pair(key, def));
1002     if (!insertStatus.second) {
1003         TF_CODING_ERROR("Duplicate creation for field '%s'", key.GetText());
1004     }
1005 
1006     return insertStatus.first->second;
1007 }
1008 
1009 SdfSchemaBase::FieldDefinition&
_DoRegisterField(const TfToken & key,const VtValue & v)1010 SdfSchemaBase::_DoRegisterField(const TfToken &key, const VtValue &v)
1011 {
1012     // The field for which we're trying to register extra schema
1013     // information must have already been created with a call to
1014     // _CreateField. See comment in SdfSchemaBase::_RegisterStandardFields.
1015     _FieldDefinitionMap::iterator fieldIt = _fieldDefinitions.find(key);
1016     if (fieldIt == _fieldDefinitions.end()) {
1017         TF_FATAL_ERROR("Field '%s' has not been created.", key.GetText());
1018     }
1019 
1020     FieldDefinition& fieldDef = fieldIt->second;
1021 
1022     // The new fallback value's type must match the type of
1023     // the fallback value the field was created with. This ensures
1024     // we stay in sync with the fields in SchemaTypeRegistration.h.
1025     if (!TfSafeTypeCompare(fieldDef.GetFallbackValue().GetTypeid(),
1026                               v.GetTypeid())) {
1027         TF_FATAL_ERROR("Registered fallback value for field '%s' does "
1028                        "not match field type definition. "
1029                        "(expected: %s, got: %s)",
1030                        key.GetText(),
1031                        fieldDef.GetFallbackValue().GetTypeName().c_str(),
1032                        v.GetTypeName().c_str());
1033     }
1034 
1035     fieldDef.FallbackValue(v);
1036     return fieldDef;
1037 }
1038 
1039 SdfSchemaBase::_SpecDefiner
_ExtendSpecDefinition(SdfSpecType specType)1040 SdfSchemaBase::_ExtendSpecDefinition(SdfSpecType specType)
1041 {
1042     if (!_specDefinitions[specType].second) {
1043         TF_FATAL_ERROR("No definition for spec type %s",
1044                        TfEnum::GetName(specType).c_str());
1045     }
1046     return _SpecDefiner(this, &_specDefinitions[specType].first);
1047 }
1048 
1049 const SdfSchemaBase::FieldDefinition*
GetFieldDefinition(const TfToken & fieldKey) const1050 SdfSchemaBase::GetFieldDefinition(const TfToken &fieldKey) const
1051 {
1052     return TfMapLookupPtr(_fieldDefinitions, fieldKey);
1053 }
1054 
1055 const VtValue&
GetFallback(const TfToken & fieldKey) const1056 SdfSchemaBase::GetFallback(const TfToken &fieldKey) const
1057 {
1058     static VtValue empty;
1059 
1060     const FieldDefinition* def = GetFieldDefinition(fieldKey);
1061     return def ? def->GetFallbackValue() : empty;
1062 }
1063 
1064 bool
IsRegistered(const TfToken & fieldKey,VtValue * fallback) const1065 SdfSchemaBase::IsRegistered(const TfToken &fieldKey, VtValue *fallback) const
1066 {
1067     const FieldDefinition* def = GetFieldDefinition(fieldKey);
1068     if (!def) {
1069         return false;
1070     }
1071 
1072     if (fallback) {
1073         *fallback = def->GetFallbackValue();
1074     }
1075 
1076     return true;
1077 }
1078 
1079 bool
HoldsChildren(const TfToken & fieldKey) const1080 SdfSchemaBase::HoldsChildren(const TfToken &fieldKey) const
1081 {
1082     const FieldDefinition* def = GetFieldDefinition(fieldKey);
1083     return (def ? def->HoldsChildren() : false);
1084 }
1085 
1086 VtValue
CastToTypeOf(const TfToken & fieldKey,const VtValue & value) const1087 SdfSchemaBase::CastToTypeOf(const TfToken &fieldKey, const VtValue &value) const
1088 {
1089     VtValue fallback;
1090     if (!SdfSchemaBase::IsRegistered(fieldKey, &fallback)) {
1091         return VtValue();
1092     }
1093 
1094     if (fallback.IsEmpty()) {
1095         return value;
1096     }
1097 
1098     return VtValue::CastToTypeOf(value, fallback);
1099 }
1100 
1101 const SdfSchemaBase::SpecDefinition*
_CheckAndGetSpecDefinition(SdfSpecType specType) const1102 SdfSchemaBase::_CheckAndGetSpecDefinition(SdfSpecType specType) const
1103 {
1104     const SpecDefinition* def = GetSpecDefinition(specType);
1105     if (!def) {
1106         TF_CODING_ERROR("No definition for spec type %s",
1107                         TfStringify(specType).c_str());
1108     }
1109 
1110     return def;
1111 }
1112 
1113 bool
IsValidFieldForSpec(const TfToken & fieldKey,SdfSpecType specType) const1114 SdfSchemaBase::IsValidFieldForSpec(const TfToken &fieldKey,
1115                                SdfSpecType specType) const
1116 {
1117     const SpecDefinition* def = _CheckAndGetSpecDefinition(specType);
1118     return (def ? def->IsValidField(fieldKey) : false);
1119 }
1120 
1121 TfTokenVector
GetFields(SdfSpecType specType) const1122 SdfSchemaBase::GetFields(SdfSpecType specType) const
1123 {
1124     const SpecDefinition* def = _CheckAndGetSpecDefinition(specType);
1125     return (def ? def->GetFields() : TfTokenVector());
1126 }
1127 
1128 TfTokenVector
GetMetadataFields(SdfSpecType specType) const1129 SdfSchemaBase::GetMetadataFields(SdfSpecType specType) const
1130 {
1131     const SpecDefinition* def = _CheckAndGetSpecDefinition(specType);
1132     return (def ? def->GetMetadataFields() : TfTokenVector());
1133 }
1134 
1135 TfToken
GetMetadataFieldDisplayGroup(SdfSpecType specType,TfToken const & metadataField) const1136 SdfSchemaBase::GetMetadataFieldDisplayGroup(SdfSpecType specType,
1137                                    TfToken const &metadataField) const
1138 {
1139     const SpecDefinition* def = _CheckAndGetSpecDefinition(specType);
1140     return (def ? def->GetMetadataFieldDisplayGroup(metadataField) : TfToken());
1141 }
1142 
1143 const TfTokenVector &
GetRequiredFields(SdfSpecType specType) const1144 SdfSchemaBase::GetRequiredFields(SdfSpecType specType) const
1145 {
1146     if (const SpecDefinition* def = _CheckAndGetSpecDefinition(specType)) {
1147         return def->GetRequiredFields();
1148     }
1149     // Intentionally leak to avoid static destruction issues.
1150     static TfTokenVector *theEmptyVector = new TfTokenVector;
1151     return *theEmptyVector;
1152 }
1153 
1154 SdfAllowed
IsValidValue(const VtValue & value) const1155 SdfSchemaBase::IsValidValue(const VtValue& value) const
1156 {
1157     if (value.IsEmpty()) {
1158         return true;
1159     }
1160 
1161     if (value.IsHolding<VtDictionary>()) {
1162         // Although dictionaries are not explicitly registered as a value
1163         // type, they are valid scene description and can be written/read
1164         // to/from layers as long as each individual value is valid scene
1165         // description. Note that we don't have to check keys because
1166         // VtDictionary's keys are always strings.
1167         //
1168         TF_FOR_ALL(it, value.UncheckedGet<VtDictionary>()) {
1169             if (SdfAllowed valueStatus = IsValidValue(it->second)) {
1170                 // Value is OK, so do nothing.
1171             }
1172             else {
1173                 const std::string error = TfStringPrintf(
1174                     "Value for key '%s' does not have a valid scene "
1175                     "description type (%s)",
1176                     it->first.c_str(), it->second.GetTypeName().c_str());
1177                 return SdfAllowed(error);
1178             }
1179         }
1180     }
1181     else if (!FindType(value)) {
1182         return SdfAllowed(
1183             "Value does not have a valid scene description type "
1184             "(" + value.GetTypeName() + ")");
1185     }
1186 
1187     return true;
1188 }
1189 
1190 std::vector<SdfValueTypeName>
GetAllTypes() const1191 SdfSchemaBase::GetAllTypes() const
1192 {
1193     return _valueTypeRegistry->GetAllTypes();
1194 }
1195 
1196 SdfValueTypeName
FindType(const TfToken & typeName) const1197 SdfSchemaBase::FindType(const TfToken& typeName) const
1198 {
1199     return _valueTypeRegistry->FindType(typeName);
1200 }
1201 
1202 SdfValueTypeName
FindType(const char * typeName) const1203 SdfSchemaBase::FindType(const char *typeName) const
1204 {
1205     return _valueTypeRegistry->FindType(TfToken(typeName));
1206 }
1207 
1208 SdfValueTypeName
FindType(const std::string & typeName) const1209 SdfSchemaBase::FindType(const std::string &typeName) const
1210 {
1211     return _valueTypeRegistry->FindType(TfToken(typeName));
1212 }
1213 
1214 SdfValueTypeName
FindType(const TfType & type,const TfToken & role) const1215 SdfSchemaBase::FindType(const TfType& type, const TfToken& role) const
1216 {
1217     return _valueTypeRegistry->FindType(type, role);
1218 }
1219 
1220 SdfValueTypeName
FindType(const VtValue & value,const TfToken & role) const1221 SdfSchemaBase::FindType(const VtValue& value, const TfToken& role) const
1222 {
1223     return _valueTypeRegistry->FindType(value, role);
1224 }
1225 
1226 SdfValueTypeName
FindOrCreateType(const TfToken & typeName) const1227 SdfSchemaBase::FindOrCreateType(const TfToken& typeName) const
1228 {
1229     return _valueTypeRegistry->FindOrCreateTypeName(typeName);
1230 }
1231 
1232 SdfSchemaBase::_ValueTypeRegistrar
_GetTypeRegistrar() const1233 SdfSchemaBase::_GetTypeRegistrar() const
1234 {
1235     return _ValueTypeRegistrar(_valueTypeRegistry.get());
1236 }
1237 
1238 SdfAllowed
IsValidIdentifier(const std::string & identifier)1239 SdfSchemaBase::IsValidIdentifier(const std::string& identifier)
1240 {
1241     if (!SdfPath::IsValidIdentifier(identifier)) {
1242         return SdfAllowed("\"" + identifier +
1243                           "\" is not a valid identifier");
1244     }
1245     return true;
1246 }
1247 
1248 SdfAllowed
IsValidNamespacedIdentifier(const std::string & identifier)1249 SdfSchemaBase::IsValidNamespacedIdentifier(const std::string& identifier)
1250 {
1251     if (!SdfPath::IsValidNamespacedIdentifier(identifier)) {
1252         return SdfAllowed("\"" + identifier +
1253                           "\" is not a valid identifier");
1254     }
1255     return true;
1256 }
1257 
1258 SdfAllowed
IsValidVariantIdentifier(const std::string & identifier)1259 SdfSchemaBase::IsValidVariantIdentifier(const std::string& identifier)
1260 {
1261     // Allow [[:alnum:]_|\-]+ with an optional leading dot.
1262 
1263     std::string::const_iterator first = identifier.begin();
1264     std::string::const_iterator last = identifier.end();
1265 
1266     // Allow optional leading dot.
1267     if (first != last && *first == '.') {
1268         ++first;
1269     }
1270 
1271     for (; first != last; ++first) {
1272         char c = *first;
1273         if (!(isalnum(c) || (c == '_') || (c == '|') || (c == '-'))) {
1274             return SdfAllowed(TfStringPrintf(
1275                     "\"%s\" is not a valid variant "
1276                     "name due to '%c' at index %d",
1277                     identifier.c_str(),
1278                     c,
1279                     (int)(first - identifier.begin())));
1280         }
1281     }
1282 
1283     return true;
1284 }
1285 
1286 SdfAllowed
IsValidRelocatesPath(const SdfPath & path)1287 SdfSchemaBase::IsValidRelocatesPath(const SdfPath& path)
1288 {
1289     if (path == SdfPath::AbsoluteRootPath()) {
1290         return SdfAllowed("Root paths not allowed in relocates map");
1291     }
1292 
1293     return true;
1294 }
1295 
1296 SdfAllowed
IsValidInheritPath(const SdfPath & path)1297 SdfSchemaBase::IsValidInheritPath(const SdfPath& path)
1298 {
1299     if (!(path.IsAbsolutePath() && path.IsPrimPath())) {
1300         return SdfAllowed("Inherit paths must be an absolute prim path");
1301     }
1302     return true;
1303 }
1304 
1305 SdfAllowed
IsValidSpecializesPath(const SdfPath & path)1306 SdfSchemaBase::IsValidSpecializesPath(const SdfPath& path)
1307 {
1308     if (!(path.IsAbsolutePath() && path.IsPrimPath())) {
1309         return SdfAllowed("Specializes paths must be absolute prim path");
1310     }
1311     return true;
1312 }
1313 
1314 SdfAllowed
IsValidAttributeConnectionPath(const SdfPath & path)1315 SdfSchemaBase::IsValidAttributeConnectionPath(const SdfPath& path)
1316 {
1317     if (path.ContainsPrimVariantSelection()) {
1318         return SdfAllowed("Attribute connection paths cannot contain "
1319                           "variant selections");
1320     }
1321     if (path.IsAbsolutePath() && (path.IsPropertyPath() || path.IsPrimPath())) {
1322         return true;
1323     }
1324     else {
1325         return SdfAllowed(
1326             TfStringPrintf("Connection paths must be absolute prim or "
1327                            "property paths: <%s>", path.GetText()));
1328     }
1329 }
1330 
1331 SdfAllowed
IsValidRelationshipTargetPath(const SdfPath & path)1332 SdfSchemaBase::IsValidRelationshipTargetPath(const SdfPath& path)
1333 {
1334     if (path.ContainsPrimVariantSelection()) {
1335         return SdfAllowed("Relationship target paths cannot contain "
1336                           "variant selections");
1337     }
1338     if (path.IsAbsolutePath() &&
1339         (path.IsPropertyPath() || path.IsPrimPath() || path.IsMapperPath())) {
1340         return true;
1341     }
1342     else {
1343         return SdfAllowed("Relationship target paths must be absolute prim, "
1344                           "property or mapper paths");
1345     }
1346 }
1347 
1348 SdfAllowed
IsValidReference(const SdfReference & ref)1349 SdfSchemaBase::IsValidReference(const SdfReference& ref)
1350 {
1351     const SdfPath& path = ref.GetPrimPath();
1352     if (!path.IsEmpty() &&
1353         !(path.IsAbsolutePath() && path.IsPrimPath())) {
1354         return SdfAllowed("Reference prim path <" + path.GetString() +
1355                           "> must be either empty or an absolute prim path");
1356     }
1357 
1358     return true;
1359 }
1360 
1361 SdfAllowed
IsValidPayload(const SdfPayload & p)1362 SdfSchemaBase::IsValidPayload(const SdfPayload& p)
1363 {
1364     const SdfPath& path = p.GetPrimPath();
1365     if (!path.IsEmpty() &&
1366         !(path.IsAbsolutePath() && path.IsPrimPath())) {
1367         return SdfAllowed("Payload prim path <" + path.GetString() +
1368                           "> must be either empty or an absolute prim path");
1369     }
1370 
1371     return true;
1372 }
1373 
1374 SdfAllowed
IsValidSubLayer(const std::string & sublayer)1375 SdfSchemaBase::IsValidSubLayer(const std::string& sublayer)
1376 {
1377     if (sublayer.empty()) {
1378         return SdfAllowed("Sublayer paths must not be empty");
1379     }
1380 
1381     // 'sublayer' must be a valid asset path as well, attempt to construct one
1382     // to check.
1383     TfErrorMark m;
1384     SdfAssetPath test(sublayer);
1385     if (!m.IsClean()) {
1386         std::vector<std::string> errs;
1387         for (TfError const &err: m) {
1388             errs.push_back(err.GetCommentary());
1389         }
1390         m.Clear();
1391         return SdfAllowed(
1392             TfStringPrintf("Invalid sublayer path: %s",
1393                            TfStringJoin(errs, "; ").c_str()));
1394     }
1395     return true;
1396 }
1397 
1398 typedef Sdf_ParserHelpers::Value Value;
1399 
1400 // Helper function that adds values of type T to the value list that are
1401 // either stored directly or stored as elements of a vector<T>. Returns true
1402 // on success and false on failure.
1403 template <typename T>
1404 static bool
_AccumulateTypedValues(const JsValue & value,std::deque<Value> * values)1405 _AccumulateTypedValues(const JsValue &value, std::deque<Value> *values) {
1406     if (value.IsArrayOf<T>()) {
1407         for (const T& v : value.GetArrayOf<T>()) {
1408             values->push_back(v);
1409         }
1410         return true;
1411     } else if (value.Is<T>()) {
1412         values->push_back(value.Get<T>());
1413         return true;
1414     }
1415     return false;
1416 }
1417 
1418 // Recursive helper function to feed the ParserValueContext with the correct
1419 // calls to BeginTuple(), EndTuple(), and TupleItem() in between calls to
1420 // AppendValue().
1421 static void
_AddValuesToValueContext(std::deque<Value> * values,Sdf_ParserValueContext * context,int level=0)1422 _AddValuesToValueContext(std::deque<Value> *values, Sdf_ParserValueContext *context, int level = 0) {
1423     if (context->valueTupleDimensions.size == 0) {
1424         while (!values->empty()) {
1425             context->AppendValue(values->front());
1426             values->pop_front();
1427         }
1428     } else if (static_cast<size_t>(level) < context->valueTupleDimensions.size) {
1429         context->BeginTuple();
1430         for (size_t i = 0; i < context->valueTupleDimensions.d[level]; i++) {
1431             _AddValuesToValueContext(values, context, level + 1);
1432         }
1433         context->EndTuple();
1434     } else if (!values->empty()) {
1435         context->AppendValue(values->front());
1436         values->pop_front();
1437     }
1438 }
1439 
1440 // Uses the ParserValueContext to manufacture a VtValue of the correct type
1441 // from a JsValue and a value typename. For example, this can manufacture a
1442 // "Vec3d[]" from a JsValue containing vector<double>(1, 2, 3, 4, 5, 6) into
1443 // VtValue(VtArray([2], Vec3d(1, 2, 3), Vec3d(4, 5, 6))). If an error occurs,
1444 // an empty VtValue is returned and the error text is stored in *errorText.
1445 static VtValue
_ParseValue(const std::string & valueTypeName,const JsValue & value,std::string * errorText)1446 _ParseValue(const std::string &valueTypeName, const JsValue &value,
1447             std::string *errorText)
1448 {
1449     // Checks for strings, ints, doubles, and vectors of those types because
1450     // that's what _ConvertDict() in Plugin.cpp parses out of plugInfo.json
1451     std::deque<Value> values;
1452     if (!_AccumulateTypedValues<std::string>(value, &values) &&
1453         !_AccumulateTypedValues<int>(value, &values) &&
1454         !_AccumulateTypedValues<double>(value, &values)) {
1455         *errorText = "Value was not a string, an int, a double, or a "
1456                      "vector of those types";
1457         return VtValue();
1458     }
1459 
1460     // Initialize the ParserValueContext
1461     Sdf_ParserValueContext context;
1462     if (!context.SetupFactory(valueTypeName)) {
1463         *errorText = TfStringPrintf("\"%s\" is not a valid type",
1464                                     valueTypeName.c_str());
1465         return VtValue();
1466     }
1467 
1468     // Feed the ParserValueContext the values in the correct format.
1469     // A better solution would be to have the default value be a string,
1470     // which is parsed using the menva file format syntax for typed values.
1471     // This would involve extracting the typed value rule out of the parser
1472     // and into a new parser.
1473     if (context.valueIsShaped)
1474         context.BeginList();
1475     while (!values.empty())
1476         _AddValuesToValueContext(&values, &context);
1477     if (context.valueIsShaped)
1478         context.EndList();
1479 
1480     // Return the produced value, or fill in errorText and return VtValue()
1481     // on failure
1482     return context.ProduceValue(errorText);
1483 }
1484 
1485 // Helper function to make reading from dictionaries easier
1486 template <typename T>
1487 static bool
_GetKey(const JsObject & dict,const std::string & key,T * value)1488 _GetKey(const JsObject &dict, const std::string &key, T *value)
1489 {
1490     JsObject::const_iterator i = dict.find(key);
1491     if (i != dict.end() && i->second.Is<T>()) {
1492         *value = i->second.Get<T>();
1493         return true;
1494     }
1495     return false;
1496 }
1497 
1498 // Helper function to read and extract from dictionaries
1499 template <typename T>
1500 static bool
_ExtractKey(JsObject & dict,const std::string & key,T * value)1501 _ExtractKey(JsObject &dict, const std::string &key, T *value)
1502 {
1503     JsObject::const_iterator i = dict.find(key);
1504     if (i != dict.end() && i->second.Is<T>()) {
1505         *value = i->second.Get<T>();
1506         dict.erase(i);
1507         return true;
1508     }
1509     return false;
1510 }
1511 
1512 static VtValue
_GetDefaultValueForListOp(const std::string & valueTypeName)1513 _GetDefaultValueForListOp(const std::string& valueTypeName)
1514 {
1515     if (valueTypeName == "intlistop") {
1516         return VtValue(SdfIntListOp());
1517     }
1518     else if (valueTypeName == "int64listop") {
1519         return VtValue(SdfInt64ListOp());
1520     }
1521     if (valueTypeName == "uintlistop") {
1522         return VtValue(SdfUIntListOp());
1523     }
1524     else if (valueTypeName == "uint64listop") {
1525         return VtValue(SdfUInt64ListOp());
1526     }
1527     if (valueTypeName == "stringlistop") {
1528         return VtValue(SdfStringListOp());
1529     }
1530     else if (valueTypeName == "tokenlistop") {
1531         return VtValue(SdfTokenListOp());
1532     }
1533     return VtValue();
1534 }
1535 
1536 static VtValue
_GetDefaultMetadataValue(const SdfSchemaBase & schema,const std::string & valueTypeName,const JsValue & defaultValue)1537 _GetDefaultMetadataValue(const SdfSchemaBase& schema,
1538                          const std::string& valueTypeName,
1539                          const JsValue& defaultValue)
1540 {
1541     if (valueTypeName == "dictionary") {
1542         if (!defaultValue.IsNull()) {
1543             // Defaults aren't allowed for dictionaries because we have
1544             // no way of parsing them at the moment
1545             TF_CODING_ERROR("Default values are not allowed on fields "
1546                             "of type \"dictionary\", which will "
1547                             "always default to an empty dictionary.");
1548             return VtValue();
1549         }
1550         return VtValue(VtDictionary());
1551     }
1552 
1553     const VtValue listOpValue = _GetDefaultValueForListOp(valueTypeName);
1554     if (!listOpValue.IsEmpty()) {
1555         if (!defaultValue.IsNull()) {
1556             // Defaults aren't allowed for list ops because we have
1557             // no way of parsing them at the moment
1558             TF_CODING_ERROR("Default values are not allowed on fields "
1559                             "of type \"%s\", which will always"
1560                             "default to an empty list op.",
1561                             valueTypeName.c_str());
1562             return VtValue();
1563         }
1564         return listOpValue;
1565     }
1566 
1567     if (const SdfValueTypeName valueType = schema.FindType(valueTypeName)) {
1568         if (defaultValue.IsNull()) {
1569             return valueType.GetDefaultValue();
1570         }
1571         else {
1572             std::string errorText;
1573             const VtValue parsedValue = _ParseValue(
1574                 valueTypeName, defaultValue, &errorText);
1575             if (parsedValue.IsEmpty()) {
1576                 TF_CODING_ERROR("Could not parse default value: %s",
1577                                 errorText.c_str());
1578             }
1579             return parsedValue;
1580         }
1581     }
1582 
1583     TF_CODING_ERROR("\"%s\" is not a registered value type",
1584                     valueTypeName.c_str());
1585     return VtValue();
1586 }
1587 
1588 // Reads and registers new fields from plugInfo.json files
1589 const std::vector<const SdfSchemaBase::FieldDefinition *>
_UpdateMetadataFromPlugins(const PlugPluginPtrVector & plugins,const std::string & tag,const _DefaultValueFactoryFn & defFactory)1590 SdfSchemaBase::_UpdateMetadataFromPlugins(
1591     const PlugPluginPtrVector& plugins,
1592     const std::string& tag,
1593     const _DefaultValueFactoryFn& defFactory)
1594 {
1595     static const std::string sdfMetadataTag = "SdfMetadata";
1596     const std::string& metadataTag = (tag.empty() ? sdfMetadataTag : tag);
1597     std::vector<const SdfSchemaBase::FieldDefinition *> metadataFieldsParsed;
1598 
1599     // Update the schema with new metadata fields from each plugin, if they
1600     // contain any
1601     for (const PlugPluginPtr & plug : plugins) {
1602         // Get the top-level dictionary key specified by the metadata tag.
1603         JsObject fields;
1604         const JsObject &metadata = plug->GetMetadata();
1605         if (!_GetKey(metadata, metadataTag, &fields))
1606             continue;
1607 
1608         // Register new fields
1609         for (const std::pair<const std::string, JsValue>& field : fields) {
1610             const TfToken fieldName(field.first);
1611 
1612             // Validate field
1613             JsObject fieldInfo;
1614             if (!_GetKey(fields, fieldName, &fieldInfo)) {
1615                 TF_CODING_ERROR("Value must be a dictionary (at \"%s\" in "
1616                                 "plugin \"%s\")",
1617                                 fieldName.GetText(),
1618                                 plug->GetPath().c_str());
1619                 continue;
1620             }
1621 
1622             std::string valueTypeName;
1623             if (!_ExtractKey(
1624                 fieldInfo, _tokens->Type.GetString(), &valueTypeName)) {
1625                 TF_CODING_ERROR("Could not read a string for \"type\" "
1626                                 "(at \"%s\" in plugin \"%s\")",
1627                                 fieldName.GetText(), plug->GetPath().c_str());
1628                 continue;
1629             }
1630 
1631             if (IsRegistered(fieldName)) {
1632                 TF_CODING_ERROR("\"%s\" is already a registered field "
1633                                 "(in plugin \"%s\")",
1634                                 fieldName.GetText(),
1635                                 plug->GetPath().c_str());
1636                 continue;
1637             }
1638 
1639             // Parse plugin-defined default value for this field.
1640             VtValue defaultValue;
1641             {
1642                 const JsValue pluginDefault =
1643                     TfMapLookupByValue(fieldInfo,
1644                     _tokens->Default.GetString(), JsValue());
1645 
1646                 TfErrorMark m;
1647 
1648                 defaultValue = _GetDefaultMetadataValue(
1649                     *this, valueTypeName, pluginDefault);
1650                 if (defaultValue.IsEmpty() && defFactory) {
1651                     defaultValue = defFactory(valueTypeName, pluginDefault);
1652                 }
1653 
1654                 if (defaultValue.IsEmpty()) {
1655                     // If an error wasn't emitted but we still don't have a
1656                     // default value, emit an error indicating this.
1657                     //
1658                     // If an error was emitted, post a follow-up error that
1659                     // provides more context about where that error was
1660                     // encountered, since the default value factory isn't
1661                     // given enough info to do this itself.
1662                     if (m.IsClean()) {
1663                         TF_CODING_ERROR("No default value for metadata "
1664                                         "(at \"%s\" in plugin \"%s\")",
1665                                         fieldName.GetText(),
1666                                         plug->GetPath().c_str());
1667                     }
1668                     else {
1669                         TF_CODING_ERROR("Error parsing default value for "
1670                                         "metadata (at \"%s\" in plugin \"%s\")",
1671                                         fieldName.GetText(),
1672                                         plug->GetPath().c_str());
1673                     }
1674                     continue;
1675                 }
1676                 else {
1677                     // We can drop errors that had been issued from
1678                     // _GetDefaultMetadataValue (e.g., due to this metadata
1679                     // type not being recognized) if the passed-in factory
1680                     // was able to produce a default value.
1681                     m.Clear();
1682                 }
1683             }
1684 
1685             // Use the supplied displayGroup, if set, otherwise 'uncategorized'.
1686             TfToken displayGroup;
1687             {
1688                 std::string displayGroupString;
1689                 if (_ExtractKey(fieldInfo,
1690                     _tokens->DisplayGroup.GetString(), &displayGroupString))
1691                     displayGroup = TfToken(displayGroupString);
1692             }
1693 
1694             FieldDefinition& fieldDef =
1695                 _RegisterField(fieldName, defaultValue, /* plugin = */ true);
1696 
1697             // Look for 'appliesTo', either a single string or a list of strings
1698             // specifying which spec types this metadatum should be registered
1699             // for.
1700             set<string> appliesTo;
1701             {
1702                 const JsValue val =
1703                     TfMapLookupByValue(fieldInfo,
1704                     _tokens->AppliesTo.GetString(), JsValue());
1705                 if (val.IsArrayOf<string>()) {
1706                     const vector<string> vec = val.GetArrayOf<string>();
1707                     appliesTo.insert(vec.begin(), vec.end());
1708                 } else if (val.Is<string>()) {
1709                     appliesTo.insert(val.Get<string>());
1710                 }
1711 
1712                 // this is so appliesTo does not show up in fieldDef's info
1713                 fieldInfo.erase(_tokens->AppliesTo.GetString());
1714             }
1715             if (appliesTo.empty() || appliesTo.count("layers")) {
1716                 _ExtendSpecDefinition(SdfSpecTypePseudoRoot)
1717                     .MetadataField(fieldName, displayGroup);
1718             }
1719 
1720             if (appliesTo.empty() || appliesTo.count("prims")) {
1721                 _ExtendSpecDefinition(SdfSpecTypePrim)
1722                     .MetadataField(fieldName, displayGroup);
1723             }
1724 
1725             if (appliesTo.empty() || appliesTo.count("properties") ||
1726                 appliesTo.count("attributes")) {
1727                 _ExtendSpecDefinition(SdfSpecTypeAttribute)
1728                     .MetadataField(fieldName, displayGroup);
1729             }
1730 
1731             if (appliesTo.empty() || appliesTo.count("properties") ||
1732                 appliesTo.count("relationships")) {
1733                 _ExtendSpecDefinition(SdfSpecTypeRelationship)
1734                     .MetadataField(fieldName, displayGroup);
1735             }
1736 
1737             // All metadata on prims should also apply to variants.
1738             // This matches how the variant spec definition is copied
1739             // from the prim spec definition in _RegisterStandardFields.
1740             if (appliesTo.empty() || appliesTo.count("variants") ||
1741                 appliesTo.count("prims")) {
1742                 _ExtendSpecDefinition(SdfSpecTypeVariant)
1743                     .MetadataField(fieldName, displayGroup);
1744             }
1745 
1746             // All remaining values in the fieldInfo will are unknown to sdf,
1747             // so store them off in our field definitions for other libraries
1748             // to use.
1749             for (const std::pair<const std::string, JsValue>& it : fieldInfo) {
1750                 const std::string& metadataInfoName = it.first;
1751                 const JsValue& metadataInfoValue = it.second;
1752 
1753                 TfToken metadataInfo (metadataInfoName);
1754                 fieldDef.AddInfo(metadataInfo, metadataInfoValue);
1755             }
1756             metadataFieldsParsed.push_back(&fieldDef);
1757         }
1758     }
1759     return metadataFieldsParsed;
1760 }
1761 
1762 void
_AddRequiredFieldName(const TfToken & fieldName)1763 SdfSchemaBase::_AddRequiredFieldName(const TfToken &fieldName)
1764 {
1765     if (find(_requiredFieldNames.begin(),
1766              _requiredFieldNames.end(), fieldName) == _requiredFieldNames.end())
1767         _requiredFieldNames.push_back(fieldName);
1768 }
1769 
1770 //
1771 // SdfSchema
1772 //
1773 
1774 TF_INSTANTIATE_SINGLETON(SdfSchema);
1775 
TF_REGISTRY_FUNCTION(TfType)1776 TF_REGISTRY_FUNCTION(TfType)
1777 {
1778     TfType::Define<SdfSchema, TfType::Bases<SdfSchemaBase> >();
1779 }
1780 
SdfSchema()1781 SdfSchema::SdfSchema()
1782 {
1783 }
1784 
~SdfSchema()1785 SdfSchema::~SdfSchema()
1786 {
1787     // Do nothing
1788 }
1789 
1790 //
1791 // Sdf_InitializeValueTypeNames
1792 //
1793 // This function is used in types.cpp to initialize the SdfValueTypeNames
1794 // static data object. This is defined here so that we can share code and
1795 // co-locate the typename strings with _AddStandardTypesToRegistry.
1796 //
1797 const Sdf_ValueTypeNamesType*
Sdf_InitializeValueTypeNames()1798 Sdf_InitializeValueTypeNames()
1799 {
1800     struct _Registry {
1801         _Registry()
1802         {
1803             _AddStandardTypesToRegistry(&registry);
1804             _AddLegacyTypesToRegistry(&registry);
1805         }
1806         Sdf_ValueTypeRegistry registry;
1807     };
1808     static const _Registry registry;
1809 
1810     const Sdf_ValueTypeRegistry& r = registry.registry;
1811     Sdf_ValueTypeNamesType* n = new Sdf_ValueTypeNamesType;
1812 
1813     n->Bool          = r.FindType("bool");
1814     n->UChar         = r.FindType("uchar");
1815     n->Int           = r.FindType("int");
1816     n->UInt          = r.FindType("uint");
1817     n->Int64         = r.FindType("int64");
1818     n->UInt64        = r.FindType("uint64");
1819     n->Half          = r.FindType("half");
1820     n->Float         = r.FindType("float");
1821     n->Double        = r.FindType("double");
1822     n->TimeCode      = r.FindType("timecode");
1823     n->String        = r.FindType("string");
1824     n->Token         = r.FindType("token");
1825     n->Asset         = r.FindType("asset");
1826     n->Int2          = r.FindType("int2");
1827     n->Int3          = r.FindType("int3");
1828     n->Int4          = r.FindType("int4");
1829     n->Half2         = r.FindType("half2");
1830     n->Half3         = r.FindType("half3");
1831     n->Half4         = r.FindType("half4");
1832     n->Float2        = r.FindType("float2");
1833     n->Float3        = r.FindType("float3");
1834     n->Float4        = r.FindType("float4");
1835     n->Double2       = r.FindType("double2");
1836     n->Double3       = r.FindType("double3");
1837     n->Double4       = r.FindType("double4");
1838     n->Point3h       = r.FindType("point3h");
1839     n->Point3f       = r.FindType("point3f");
1840     n->Point3d       = r.FindType("point3d");
1841     n->Vector3h      = r.FindType("vector3h");
1842     n->Vector3f      = r.FindType("vector3f");
1843     n->Vector3d      = r.FindType("vector3d");
1844     n->Normal3h      = r.FindType("normal3h");
1845     n->Normal3f      = r.FindType("normal3f");
1846     n->Normal3d      = r.FindType("normal3d");
1847     n->Color3h       = r.FindType("color3h");
1848     n->Color3f       = r.FindType("color3f");
1849     n->Color3d       = r.FindType("color3d");
1850     n->Color4h       = r.FindType("color4h");
1851     n->Color4f       = r.FindType("color4f");
1852     n->Color4d       = r.FindType("color4d");
1853     n->Quath         = r.FindType("quath");
1854     n->Quatf         = r.FindType("quatf");
1855     n->Quatd         = r.FindType("quatd");
1856     n->Matrix2d      = r.FindType("matrix2d");
1857     n->Matrix3d      = r.FindType("matrix3d");
1858     n->Matrix4d      = r.FindType("matrix4d");
1859     n->Frame4d       = r.FindType("frame4d");
1860     n->TexCoord2f    = r.FindType("texCoord2f");
1861     n->TexCoord2d    = r.FindType("texCoord2d");
1862     n->TexCoord2h    = r.FindType("texCoord2h");
1863     n->TexCoord3f    = r.FindType("texCoord3f");
1864     n->TexCoord3d    = r.FindType("texCoord3d");
1865     n->TexCoord3h    = r.FindType("texCoord3h");
1866 
1867     n->BoolArray     = r.FindType("bool[]");
1868     n->UCharArray    = r.FindType("uchar[]");
1869     n->IntArray      = r.FindType("int[]");
1870     n->UIntArray     = r.FindType("uint[]");
1871     n->Int64Array    = r.FindType("int64[]");
1872     n->UInt64Array   = r.FindType("uint64[]");
1873     n->HalfArray     = r.FindType("half[]");
1874     n->FloatArray    = r.FindType("float[]");
1875     n->DoubleArray   = r.FindType("double[]");
1876     n->TimeCodeArray = r.FindType("timecode[]");
1877     n->StringArray   = r.FindType("string[]");
1878     n->TokenArray    = r.FindType("token[]");
1879     n->AssetArray    = r.FindType("asset[]");
1880     n->Int2Array     = r.FindType("int2[]");
1881     n->Int3Array     = r.FindType("int3[]");
1882     n->Int4Array     = r.FindType("int4[]");
1883     n->Half2Array    = r.FindType("half2[]");
1884     n->Half3Array    = r.FindType("half3[]");
1885     n->Half4Array    = r.FindType("half4[]");
1886     n->Float2Array   = r.FindType("float2[]");
1887     n->Float3Array   = r.FindType("float3[]");
1888     n->Float4Array   = r.FindType("float4[]");
1889     n->Double2Array  = r.FindType("double2[]");
1890     n->Double3Array  = r.FindType("double3[]");
1891     n->Double4Array  = r.FindType("double4[]");
1892     n->Point3hArray  = r.FindType("point3h[]");
1893     n->Point3fArray  = r.FindType("point3f[]");
1894     n->Point3dArray  = r.FindType("point3d[]");
1895     n->Vector3hArray = r.FindType("vector3h[]");
1896     n->Vector3fArray = r.FindType("vector3f[]");
1897     n->Vector3dArray = r.FindType("vector3d[]");
1898     n->Normal3hArray = r.FindType("normal3h[]");
1899     n->Normal3fArray = r.FindType("normal3f[]");
1900     n->Normal3dArray = r.FindType("normal3d[]");
1901     n->Color3hArray  = r.FindType("color3h[]");
1902     n->Color3fArray  = r.FindType("color3f[]");
1903     n->Color3dArray  = r.FindType("color3d[]");
1904     n->Color4hArray  = r.FindType("color4h[]");
1905     n->Color4fArray  = r.FindType("color4f[]");
1906     n->Color4dArray  = r.FindType("color4d[]");
1907     n->QuathArray    = r.FindType("quath[]");
1908     n->QuatfArray    = r.FindType("quatf[]");
1909     n->QuatdArray    = r.FindType("quatd[]");
1910     n->Matrix2dArray = r.FindType("matrix2d[]");
1911     n->Matrix3dArray = r.FindType("matrix3d[]");
1912     n->Matrix4dArray = r.FindType("matrix4d[]");
1913     n->Frame4dArray  = r.FindType("frame4d[]");
1914     n->TexCoord2fArray = r.FindType("texCoord2f[]");
1915     n->TexCoord2dArray = r.FindType("texCoord2d[]");
1916     n->TexCoord2hArray = r.FindType("texCoord2h[]");
1917     n->TexCoord3fArray = r.FindType("texCoord3f[]");
1918     n->TexCoord3dArray = r.FindType("texCoord3d[]");
1919     n->TexCoord3hArray = r.FindType("texCoord3h[]");
1920 
1921     return n;
1922 }
1923 
1924 PXR_NAMESPACE_CLOSE_SCOPE
1925