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_PRIM_SPEC_H
25 #define PXR_USD_SDF_PRIM_SPEC_H
26 
27 /// \file sdf/primSpec.h
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usd/sdf/declareSpec.h"
31 #include "pxr/usd/sdf/spec.h"
32 #include "pxr/usd/sdf/path.h"
33 #include "pxr/usd/sdf/payload.h"
34 #include "pxr/usd/sdf/proxyTypes.h"
35 #include "pxr/usd/sdf/types.h"
36 #include "pxr/usd/sdf/api.h"
37 #include "pxr/base/tf/declarePtrs.h"
38 
39 #include <iosfwd>
40 #include <map>
41 #include <string>
42 #include <vector>
43 
44 PXR_NAMESPACE_OPEN_SCOPE
45 
46 /// \class SdfPrimSpec
47 ///
48 /// Represents a prim description in an SdfLayer object.
49 ///
50 /// Every SdfPrimSpec object is defined in a layer.  It is identified by its
51 /// path (SdfPath class) in the namespace hierarchy of its layer.  SdfPrimSpecs
52 /// can be created using the New() method as children of either the containing
53 /// SdfLayer itself (for "root level" prims), or as children of other
54 /// SdfPrimSpec objects to extend a hierarchy.  The helper function
55 /// SdfCreatePrimInLayer() can be used to quickly create a hierarchy of
56 /// primSpecs.
57 ///
58 /// SdfPrimSpec objects have properties of two general types: attributes
59 /// (containing values) and relationships (different types of connections to
60 /// other prims and attributes).  Attributes are represented by the
61 /// SdfAttributeSpec class and relationships by the SdfRelationshipSpec class.
62 /// Each prim has its own namespace of properties.  Properties are stored and
63 /// accessed by their name.
64 ///
65 /// SdfPrimSpec objects have a typeName, permission restriction, and they
66 /// reference and inherit prim paths.  Permission restrictions control which
67 /// other layers may refer to, or express opinions about a prim. See the
68 /// SdfPermission class for more information.
69 ///
70 /// \todo
71 /// \li Insert doc about references and inherits here.
72 /// \li Should have validate... methods for name, children, properties
73 ///
74 class SdfPrimSpec : public SdfSpec
75 {
76     SDF_DECLARE_SPEC(SdfPrimSpec, SdfSpec);
77 
78 public:
79     typedef SdfPrimSpecView NameChildrenView;
80     typedef SdfPropertySpecView PropertySpecView;
81     typedef SdfAttributeSpecView AttributeSpecView;
82     typedef SdfRelationshipSpecView RelationshipSpecView;
83 
84     ///
85     /// \name Spec creation
86     /// @{
87 
88     /// Create a root prim spec.
89     ///
90     /// Creates a prim spec with a \p name, \p specifier and \p typeName as a
91     /// root prim in the given layer.
92     SDF_API
93     static SdfPrimSpecHandle
94     New(const SdfLayerHandle& parentLayer,
95         const std::string& name, SdfSpecifier spec,
96         const std::string& typeName = std::string());
97 
98     /// Create a prim spec.
99     ///
100     /// Creates a prim spec with a \p name, \p specifier and \p typeName as
101     /// a namespace child of the given prim.
102     ///
103     /// \sa SdfCreatePrimInLayer() to create a PrimSpec with all required
104     /// ancestor specs as SdfSpecifierOver.
105     SDF_API
106     static SdfPrimSpecHandle
107     New(const SdfPrimSpecHandle& parentPrim,
108         const std::string& name, SdfSpecifier spec,
109         const std::string& typeName = std::string());
110 
111     /// \name Name
112     /// @{
113 
114     /// Returns the prim's name.
115     SDF_API
116     const std::string& GetName() const;
117 
118     /// Returns the prim's name, as a token.
119     SDF_API
120     TfToken GetNameToken() const;
121 
122     /// Returns true if setting the prim spec's name to \p newName will
123     /// succeed.
124     ///
125     /// Returns false if it won't, and sets \p whyNot with a string
126     /// describing why not.
127     SDF_API
128     bool CanSetName(const std::string& newName, std::string* whyNot) const;
129 
130     /// Sets the prim's name.
131     ///
132     /// Children prims must be unique by name. It is an error to
133     /// set the name to the same name as an existing child of this
134     /// prim's parent.
135     ///
136     /// Setting validate to false, will skip validation of the \p newName
137     /// (that is, CanSetName will not be called).
138     ///
139     /// Returns true if successful, false otherwise.
140     SDF_API
141     bool SetName(const std::string& newName, bool validate = true);
142 
143     /// Returns true if the given string is a valid prim name.
144     SDF_API
145     static bool IsValidName(const std::string& name);
146 
147     /// @}
148     /// \name Namespace hierarchy
149     /// @{
150 
151     /// Returns the prim's namespace pseudo-root prim.
152     SDF_API
153     SdfPrimSpecHandle GetNameRoot() const;
154 
155     /// Returns the prim's namespace parent.
156     ///
157     /// This does not return the pseudo-root for root prims.  Most
158     /// algorithms that scan the namespace hierarchy upwards don't
159     /// want to process the pseudo-root the same way as actual prims.
160     /// Algorithms that do can always call \c GetRealNameParent().
161     SDF_API
162     SdfPrimSpecHandle GetNameParent() const;
163 
164     /// Returns the prim's namespace parent.
165     SDF_API
166     SdfPrimSpecHandle GetRealNameParent() const;
167 
168     /// Returns a keyed vector view of the prim's namespace children.
169     SDF_API
170     NameChildrenView GetNameChildren() const;
171 
172     /// Updates nameChildren to match the given vector of prims.
173     SDF_API
174     void SetNameChildren(const SdfPrimSpecHandleVector&);
175 
176     /// Inserts a child.
177     ///
178     /// \p index is ignored except for range checking;  -1 is permitted.
179     ///
180     /// Returns true if successful, false if failed.
181     SDF_API
182     bool InsertNameChild(const SdfPrimSpecHandle& child, int index = -1);
183 
184     /// Removes the child.  Returns true if successful, false if failed.
185     SDF_API
186     bool RemoveNameChild(const SdfPrimSpecHandle& child);
187 
188     /// Returns the list of child names for this prim's reorder.
189     /// nameChildren statement.
190     ///
191     /// See SetNameChildrenOrder() for more info.
192     SDF_API
193     SdfNameChildrenOrderProxy GetNameChildrenOrder() const;
194 
195     /// Returns true if this prim has name children order specified
196     SDF_API
197     bool HasNameChildrenOrder() const;
198 
199     /// Given a list of (possibly sparse) child names, authors a reorder
200     /// nameChildren statement for this prim.
201     ///
202     /// The reorder statement can modify the order of name children
203     /// during composition.  This order doesn't affect GetNameChildren(),
204     /// InsertNameChild(), SetNameChildren(), et al.
205     SDF_API
206     void SetNameChildrenOrder(const std::vector<TfToken>& names);
207 
208     /// Adds a new name child \p name in the name children order.
209     /// If \p index is -1, the name is inserted at the end.
210     SDF_API
211     void InsertInNameChildrenOrder(const TfToken& name, int index = -1);
212 
213     /// Removes a name child name from the name children order.
214     SDF_API
215     void RemoveFromNameChildrenOrder(const TfToken& name);
216 
217     /// Removes a name child name from the name children order by index.
218     SDF_API
219     void RemoveFromNameChildrenOrderByIndex(int index);
220 
221     /// Reorders the given list of child names according to the reorder
222     /// nameChildren statement for this prim.
223     ///
224     /// This routine employs the standard list editing operation for ordered
225     /// items in a ListEditor.
226     SDF_API
227     void ApplyNameChildrenOrder(std::vector<TfToken>* vec) const;
228 
229     /// @}
230     /// \name Properties
231     /// @{
232 
233     /// Returns the prim's properties.
234     SDF_API
235     PropertySpecView GetProperties() const;
236 
237     /// Updates properties to match the given vector of properties.
238     SDF_API
239     void SetProperties(const SdfPropertySpecHandleVector&);
240 
241     /// Inserts a property.
242     ///
243     /// \p index is ignored except for range checking;  -1 is permitted.
244     ///
245     /// Returns true if successful, false if failed.
246     SDF_API
247     bool InsertProperty(const SdfPropertySpecHandle& property, int index = -1);
248 
249     /// Removes the property.
250     SDF_API
251     void RemoveProperty(const SdfPropertySpecHandle& property);
252 
253     /// Returns a view of the attributes of this prim.
254     SDF_API
255     AttributeSpecView GetAttributes() const;
256 
257     /// Returns a view of the relationships of this prim.
258     SDF_API
259     RelationshipSpecView GetRelationships() const;
260 
261     /// Returns the list of property names for this prim's reorder
262     /// properties statement.
263     ///
264     /// See SetPropertyOrder() for more info.
265     SDF_API
266     SdfPropertyOrderProxy GetPropertyOrder() const;
267 
268     /// Returns true if this prim has a property ordering specified.
269     SDF_API
270     bool HasPropertyOrder() const;
271 
272     /// Given a list of (possibly sparse) property names, authors a
273     /// reorder properties statement for this prim.
274     ///
275     /// The reorder statement can modify the order of properties during
276     /// composition.  This order doesn't affect GetProperties(),
277     /// InsertProperty(), SetProperties(), et al.
278     SDF_API
279     void SetPropertyOrder(const std::vector<TfToken>& names);
280 
281     /// Add a new property \p name in the property order.
282     /// If \p index is -1, the name is inserted at the end.
283     SDF_API
284     void InsertInPropertyOrder(const TfToken& name, int index = -1);
285 
286     /// Remove a property name from the property order.
287     SDF_API
288     void RemoveFromPropertyOrder(const TfToken& name);
289 
290     /// Remove a property name from the property order by index.
291     SDF_API
292     void RemoveFromPropertyOrderByIndex(int index);
293 
294     /// Reorders the given list of property names according to the
295     /// reorder properties statement for this prim.
296     ///
297     /// This routine employs the standard list editing operation for ordered
298     /// items in a ListEditor.
299     SDF_API
300     void ApplyPropertyOrder(std::vector<TfToken>* vec) const;
301 
302     /// @}
303     /// \name Lookup
304     /// @{
305 
306     /// Returns the object for the given \p path.
307     ///
308     /// If \p path is relative then it will be interpreted as
309     /// relative to this prim.  If it is absolute then it will be
310     /// interpreted as absolute in this prim's layer.
311     ///
312     /// Returns invalid handle if there is no object at \p path.
313     SDF_API
314     SdfSpecHandle GetObjectAtPath(const SdfPath& path) const;
315 
316     /// Returns a prim given its \p path.
317     ///
318     /// Returns invalid handle if there is no prim at \p path.
319     /// This is simply a more specifically typed version of GetObjectAtPath.
320     SDF_API
321     SdfPrimSpecHandle GetPrimAtPath(const SdfPath& path) const;
322 
323     /// Returns a property given its \p path.
324     ///
325     /// Returns invalid handle if there is no property at \p path.
326     /// This is simply a more specifically typed version of GetObjectAtPath.
327     SDF_API
328     SdfPropertySpecHandle GetPropertyAtPath(const SdfPath& path) const;
329 
330     /// Returns an attribute given its \p path.
331     ///
332     /// Returns invalid handle if there is no attribute at \p path.
333     /// This is simply a more specifically typed version of GetObjectAtPath.
334     SDF_API
335     SdfAttributeSpecHandle GetAttributeAtPath(const SdfPath& path) const;
336 
337     /// Returns a relationship given its \p path.
338     ///
339     /// Returns invalid handle if there is no relationship at \p path.
340     /// This is simply a more specifically typed version of GetObjectAtPath.
341     SDF_API
342     SdfRelationshipSpecHandle GetRelationshipAtPath(const SdfPath& path) const;
343 
344     /// @}
345     /// \name Metadata
346     /// @{
347 
348     /// Returns the typeName of the model prim.
349     ///
350     /// For prims this specifies the sub-class of MfPrim that
351     /// this prim describes.
352     ///
353     /// The default value for typeName is the empty token.
354     SDF_API
355     TfToken GetTypeName() const;
356 
357     /// Sets the typeName of the model prim.
358     SDF_API
359     void SetTypeName(const std::string& value);
360 
361     /// Returns the comment string for this prim spec.
362     ///
363     /// The default value for comment is @"".
364     SDF_API
365     std::string GetComment() const;
366 
367     /// Sets the comment string for this prim spec.
368     SDF_API
369     void SetComment(const std::string& value);
370 
371     /// Returns the documentation string for this prim spec.
372     ///
373     /// The default value for documentation is @"".
374     SDF_API
375     std::string GetDocumentation() const;
376 
377     /// Sets the documentation string for this prim spec.
378     SDF_API
379     void SetDocumentation(const std::string& value);
380 
381     /// Returns whether this prim spec is active.
382     ///
383     /// The default value for active is true.
384     SDF_API
385     bool GetActive() const;
386 
387     /// Sets whether this prim spec is active.
388     SDF_API
389     void SetActive(bool value);
390 
391     /// Returns true if this prim spec has an opinion about active.
392     SDF_API
393     bool HasActive() const;
394 
395     /// Removes the active opinion in this prim spec if there is one.
396     SDF_API
397     void ClearActive();
398 
399     /// Returns whether this prim spec will be hidden in browsers.
400     ///
401     /// The default value for hidden is false.
402     SDF_API
403     bool GetHidden() const;
404 
405     /// Sets whether this prim spec will be hidden in browsers.
406     SDF_API
407     void SetHidden( bool value );
408 
409     /// Returns this prim spec's kind.
410     ///
411     /// The default value for kind is an empty \c TfToken.
412     SDF_API
413     TfToken GetKind() const;
414 
415     /// Sets this prim spec's kind.
416     SDF_API
417     void SetKind(const TfToken& value);
418 
419     /// Returns true if this prim spec has an opinion about kind.
420     SDF_API
421     bool HasKind() const;
422 
423     /// Remove the kind opinion from this prim spec if there is one.
424     SDF_API
425     void ClearKind();
426 
427     /// Returns the symmetry function for this prim.
428     ///
429     /// The default value for symmetry function is an empty token.
430     SDF_API
431     TfToken GetSymmetryFunction() const;
432 
433     /// Sets the symmetry function for this prim.
434     ///
435     /// If \p functionName is an empty token, then this removes any symmetry
436     /// function for the given prim.
437     SDF_API
438     void SetSymmetryFunction(const TfToken& functionName);
439 
440     /// Returns the symmetry arguments for this prim.
441     ///
442     /// The default value for symmetry arguments is an empty dictionary.
443     SDF_API
444     SdfDictionaryProxy GetSymmetryArguments() const;
445 
446     /// Sets a symmetry argument for this prim.
447     ///
448     /// If \p value is empty, then this removes the setting
449     /// for the given symmetry argument \p name.
450     SDF_API
451     void SetSymmetryArgument(const std::string& name, const VtValue& value);
452 
453     /// Returns the symmetric peer for this prim.
454     ///
455     /// The default value for symmetric peer is an empty string.
456     SDF_API
457     std::string GetSymmetricPeer() const;
458 
459     /// Sets a symmetric peer for this prim.
460     ///
461     /// If \p peerName is empty, then this removes the symmetric peer
462     /// for this prim.
463     SDF_API
464     void SetSymmetricPeer(const std::string& peerName);
465 
466     /// Returns the prefix string for this prim spec.
467     ///
468     /// The default value for prefix is "".
469     SDF_API
470     std::string GetPrefix() const;
471 
472     /// Sets the prefix string for this prim spec.
473     SDF_API
474     void SetPrefix(const std::string& value);
475 
476     /// Returns the suffix string for this prim spec.
477     ///
478     /// The default value for suffix is "".
479     SDF_API
480     std::string GetSuffix() const;
481 
482     /// Sets the suffix string for this prim spec.
483     SDF_API
484     void SetSuffix(const std::string& value);
485 
486     /// Returns the custom data for this prim.
487     ///
488     /// The default value for custom data is an empty dictionary.
489     ///
490     /// Custom data is for use by plugins or other non-tools supplied
491     /// extensions that need to be able to store data attached to arbitrary
492     /// scene objects.  Note that if the only objects you want to store data
493     /// on are prims, using custom attributes is probably a better choice.
494     /// But if you need to possibly store this data on attributes or
495     /// relationships or as annotations on reference arcs, then custom data
496     /// is an appropriate choice.
497     SDF_API
498     SdfDictionaryProxy GetCustomData() const;
499 
500     /// Returns the asset info dictionary for this prim.
501     ///
502     /// The default value is an empty dictionary.
503     ///
504     /// The asset info dictionary is used to annotate prims representing the
505     /// root-prims of assets (generally organized as models) with various
506     /// data related to asset management. For example, asset name, root layer
507     /// identifier, asset version etc.
508     ///
509     SDF_API
510     SdfDictionaryProxy GetAssetInfo() const;
511 
512     /// Sets a custom data entry for this prim.
513     ///
514     /// If \p value is empty, then this removes the given custom data entry.
515     SDF_API
516     void SetCustomData(const std::string& name, const VtValue& value);
517 
518     /// Sets a asset info entry for this prim.
519     ///
520     /// If \p value is empty, then this removes the given asset info entry.
521     ///
522     /// \sa GetAssetInfo()
523     ///
524     SDF_API
525     void SetAssetInfo(const std::string& name, const VtValue& value);
526 
527     /// Returns the spec specifier (def, over or class).
528     SDF_API
529     SdfSpecifier GetSpecifier() const;
530 
531     /// Sets the spec specifier (def or over).
532     SDF_API
533     void SetSpecifier(SdfSpecifier value);
534 
535     /// Returns the prim's permission restriction.
536     ///
537     /// The default value for permission is SdfPermissionPublic.
538     SDF_API
539     SdfPermission GetPermission() const;
540 
541     /// Sets the prim's permission restriction.
542     SDF_API
543     void SetPermission(SdfPermission value);
544 
545     /// Returns the prefixSubstitutions dictionary for this prim spec.
546     ///
547     /// The default value for prefixSubstitutions is an empty VtDictionary.
548     SDF_API
549     VtDictionary GetPrefixSubstitutions() const;
550 
551     /// Sets the \p prefixSubstitutions dictionary for this prim spec.
552     SDF_API
553     void SetPrefixSubstitutions(const VtDictionary& prefixSubstitutions);
554 
555     /// Returns the suffixSubstitutions dictionary for this prim spec.
556     ///
557     /// The default value for suffixSubstitutions is an empty VtDictionary.
558     SDF_API
559     VtDictionary GetSuffixSubstitutions() const;
560 
561     /// Sets the \p suffixSubstitutions dictionary for this prim spec.
562     SDF_API
563     void SetSuffixSubstitutions(const VtDictionary& suffixSubstitutions);
564 
565     /// Sets the value for the prim's instanceable flag.
566     SDF_API
567     void SetInstanceable(bool instanceable);
568 
569     /// Returns the value for the prim's instanceable flag.
570     SDF_API
571     bool GetInstanceable() const;
572 
573     /// Returns true if this prim spec has a value authored for its
574     /// instanceable flag, false otherwise.
575     SDF_API
576     bool HasInstanceable() const;
577 
578     /// Clears the value for the prim's instanceable flag.
579     SDF_API
580     void ClearInstanceable();
581 
582     /// @}
583     /// \name Payloads
584     /// @{
585 
586     /// Returns a proxy for the prim's payloads.
587     ///
588     /// Payloads for this prim may be modified through the proxy.
589     SDF_API
590     SdfPayloadsProxy GetPayloadList() const;
591 
592     /// Returns true if this prim has payloads set.
593     SDF_API
594     bool HasPayloads() const;
595 
596     /// Clears the payloads for this prim.
597     SDF_API
598     void ClearPayloadList();
599 
600     /// @}
601     /// \name Inherits
602     /// @{
603 
604     /// Returns a proxy for the prim's inherit paths.
605     ///
606     /// Inherit paths for this prim may be modified through the proxy.
607     SDF_API
608     SdfInheritsProxy GetInheritPathList() const;
609 
610     /// Returns true if this prim has inherit paths set.
611     SDF_API
612     bool HasInheritPaths() const;
613 
614     /// Clears the inherit paths for this prim.
615     SDF_API
616     void ClearInheritPathList();
617 
618     /// @}
619     /// \name Specializes
620     /// @{
621 
622     /// Returns a proxy for the prim's specializes paths.
623     ///
624     /// Specializes for this prim may be modified through the proxy.
625     SDF_API
626     SdfSpecializesProxy GetSpecializesList() const;
627 
628     /// Returns true if this prim has specializes set.
629     SDF_API
630     bool HasSpecializes() const;
631 
632     /// Clears the specializes for this prim.
633     SDF_API
634     void ClearSpecializesList();
635 
636     /// @}
637     /// \name References
638     /// @{
639 
640     /// Returns a proxy for the prim's references.
641     ///
642     /// References for this prim may be modified through the proxy.
643     SDF_API
644     SdfReferencesProxy GetReferenceList() const;
645 
646     /// Returns true if this prim has references set.
647     SDF_API
648     bool HasReferences() const;
649 
650     /// Clears the references for this prim.
651     SDF_API
652     void ClearReferenceList();
653 
654     /// @}
655     /// \name Variants
656     /// @{
657 
658     /// Returns a proxy for the prim's variant sets.
659     ///
660     /// Variant sets for this prim may be modified through the proxy.
661     SDF_API
662     SdfVariantSetNamesProxy GetVariantSetNameList() const;
663 
664     /// Returns true if this prim has variant sets set.
665     SDF_API
666     bool HasVariantSetNames() const;
667 
668     /// Returns list of variant names for the given variant set.
669     SDF_API
670     std::vector<std::string> GetVariantNames(const std::string& name) const;
671 
672     /// Returns the variant sets.
673     ///
674     /// The result maps variant set names to variant sets.  Variant sets
675     /// may be removed through the proxy.
676     SDF_API
677     SdfVariantSetsProxy GetVariantSets() const;
678 
679     /// Removes the variant set with the given \a name.
680     ///
681     /// Note that the set's name should probably also be removed from
682     /// the variant set names list.
683     SDF_API
684     void RemoveVariantSet(const std::string& name);
685 
686     /// Returns an editable map whose keys are variant set names and
687     /// whose values are the variants selected for each set.
688     SDF_API
689     SdfVariantSelectionProxy GetVariantSelections() const;
690 
691     /// Sets the variant selected for the given variant set.
692     /// If \p variantName is empty, then this removes the variant
693     /// selection opinion for the variant set \p variantSetName. To
694     /// explicitly set the variant selection to be empty, use
695     /// BlockVariantSelection instead.
696     SDF_API
697     void SetVariantSelection(const std::string& variantSetName,
698                              const std::string& variantName);
699 
700     /// Blocks the variant selected for the given variant set by setting
701     /// the variant selection to empty.
702     SDF_API
703     void BlockVariantSelection(const std::string& variantSetName);
704 
705     /// @}
706     /// \name Relocates
707     /// @{
708 
709     /// Get an editing proxy for the map of namespace relocations
710     /// specified on this prim.
711     ///
712     /// The map of namespace relocation paths is editable in-place via
713     /// this editing proxy.  Individual source-target pairs can be added,
714     /// removed, or altered using common map operations.
715     ///
716     /// The map is organized as target \c SdfPath indexed by source \c SdfPath.
717     /// Key and value paths are stored as absolute regardless of how they're
718     /// added.
719     SDF_API
720     SdfRelocatesMapProxy GetRelocates() const;
721 
722     /// Set the entire map of namespace relocations specified on this prim.
723     /// Use the editing proxy for modifying single paths in the map.
724     SDF_API
725     void SetRelocates(const SdfRelocatesMap& newMap);
726 
727     /// Returns true if this prim has any relocates opinion, including
728     /// that there should be no relocates (i.e. an empty map).  An empty
729     /// map (no relocates) does not mean the same thing as a missing map
730     /// (no opinion).
731     SDF_API
732     bool HasRelocates() const;
733 
734     /// Clears the relocates opinion for this prim.
735     SDF_API
736     void ClearRelocates();
737 
738     /// @}
739 
740 private:
741     // Returns true if this object is the pseudo-root.
742     bool _IsPseudoRoot() const;
743 
744     // Raises an error and returns false if this is the pseudo-root,
745     // otherwise returns true.  We want to allow clients to be able
746     // to use pseudo-roots as any other prim in namespace editing
747     // operations as well as silently permit read accesses on fields
748     // pseudo-roots don't actually have in order to promote generic
749     // algorithm programming.  Mutating methods on SdfPrimSpec use
750     // this function as write access validation.
751     bool _ValidateEdit(const TfToken& key) const;
752 
753 private:
754     static SdfPrimSpecHandle
755     _New(const SdfPrimSpecHandle &parentPrim,
756          const TfToken &name, SdfSpecifier spec,
757          const TfToken &typeName);
758 };
759 
760 /// Convenience function to create a prim at the given path, and any
761 /// necessary parent prims, in the given layer.
762 ///
763 /// If a prim already exists at the given path it will be returned
764 /// unmodified.
765 ///
766 /// The new specs are created with SdfSpecifierOver and an empty type.
767 /// primPath must be a valid prim path.
768 SDF_API
769 SdfPrimSpecHandle SdfCreatePrimInLayer(const SdfLayerHandle& layer,
770                                        const SdfPath& primPath);
771 
772 
773 /// Convenience function to create a prim at the given path, and any
774 /// necessary parent prims, in the given layer.
775 ///
776 /// If a prim already exists at the given path, do nothing and return true.
777 ///
778 /// Any newly created specs have SdfSpecifierOver and an empty type.  primPath
779 /// must be a valid prim path.  Return false and issue an error if we fail to
780 /// author the required scene description.
781 SDF_API
782 bool SdfJustCreatePrimInLayer(const SdfLayerHandle& layer,
783                               const SdfPath& primPath);
784 
785 PXR_NAMESPACE_CLOSE_SCOPE
786 
787 #endif // PXR_USD_SDF_PRIM_SPEC_H
788