text: //
  // Copyright 2018 Pixar
  //
  // Licensed under the Apache License, Version 2.0 (the "Apache License")
  // with the following modification; you may not use this file except in
  // compliance with the Apache License and the following modification to it:
  // Section 6. Trademarks. is deleted and replaced with:
  //
  // 6. Trademarks. This License does not grant permission to use the trade
  //    names, trademarks, service marks, or product names of the Licensor
  //    and its affiliates, except as required to comply with Section 4(c) of
  //    the License and to reproduce the content of the NOTICE file.
  //
  // You may obtain a copy of the Apache License at
  //
  //     http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the Apache License with the above modification is
  // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  // KIND, either express or implied. See the Apache License for the specific
  // language governing permissions and limitations under the Apache License.
  //
  
  #ifndef PXR_USD_NDR_PROPERTY_H
  #define PXR_USD_NDR_PROPERTY_H
  
  /// \file ndr/property.h
  
  #include "pxr/pxr.h"
  #include "pxr/usd/ndr/api.h"
  #include "pxr/base/tf/token.h"
  #include "pxr/base/vt/value.h"
  #include "pxr/usd/ndr/declare.h"
  
  PXR_NAMESPACE_OPEN_SCOPE
  
  /// \class NdrProperty
  ///
  /// Represents a property (input or output) that is part of a `NdrNode`
  /// instance.
  ///
  /// A property must have a name and type, but may also specify a host of
  /// additional metadata. Instances can also be queried to determine if another
  /// `NdrProperty` instance can be connected to it.
  ///
  /// In almost all cases, this class will not be used directly. More specialized
  /// properties can be created that derive from `NdrProperty`; those specialized
  /// properties can add their own domain-specific data and methods.
  class NdrProperty
  {
  public:
      /// Constructor.
      NDR_API
      NdrProperty(
          const TfToken& name,
          const TfToken& type,
          const VtValue& defaultValue,
          bool isOutput,
          size_t arraySize,
          bool isDynamicArray,
          const NdrTokenMap& metadata
      );
  
      /// Destructor.
      NDR_API
      virtual ~NdrProperty();
  
      /// \name The Basics
      /// @{
  
      /// Gets the name of the property.
      NDR_API
      const TfToken& GetName() const { return _name; }
  
      /// Gets the type of the property.
      NDR_API
      const TfToken& GetType() const { return _type; }
  
      /// Gets this property's default value.
      NDR_API
      const VtValue& GetDefaultValue() const { return _defaultValue; }
  
      /// Whether this property is an output.
      NDR_API
      bool IsOutput() const { return _isOutput; }
  
      /// Whether this property's type is an array type.
      NDR_API
      bool IsArray() const { return (_arraySize > 0) || _isDynamicArray; }
  
      /// Whether this property's array type is dynamically-sized.
      NDR_API
      bool IsDynamicArray() const { return _isDynamicArray; };
  
      /// Gets this property's array size.
      ///
      /// If this property is a fixed-size array type, the array size is returned.
      /// In the case of a dynamically-sized array, this method returns the array
      /// size that the parser reports, and should not be relied upon to be
      /// accurate. A parser may report -1 for the array size, for example, to
      /// indicate a dynamically-sized array. For types that are not a fixed-size
      /// array or dynamic array, this returns 0.
      NDR_API
      int GetArraySize() const { return _arraySize; }
  
      /// Gets a string with basic information about this property. Helpful for
      /// things like adding this property to a log.
      NDR_API
      virtual std::string GetInfoString() const;
  
      /// @}
  
  
      /// \name Metadata
      /// The metadata returned here is a direct result of what the parser plugin
      /// is able to determine about the node. See the documentation for a
      /// specific parser plugin to get help on what the parser is looking for to
      /// populate these values.
      /// @{
  
      /// All of the metadata that came from the parse process.
      NDR_API
      virtual const NdrTokenMap& GetMetadata() const { return _metadata; }
  
      /// @}
  
  
      /// \name Connection Information
      /// @{
  
      /// Whether this property can be connected to other properties.
      NDR_API
      virtual bool IsConnectable() const;
  
      /// Determines if this property can be connected to the specified property.
      NDR_API
      virtual bool CanConnectTo(const NdrProperty& other) const;
  
      /// @}
  
  
      /// \name Utilities
      /// @{
  
      /// Converts the property's type from `GetType()` into a `SdfValueTypeName`.
      ///
      /// Two scenarios can result: an exact mapping from property type to Sdf
      /// type, and an inexact mapping. In the first scenario, the first element
      /// in the pair will be the cleanly-mapped Sdf type, and the second element,
      /// a TfToken, will be empty. In the second scenario, the Sdf type will be
      /// set to `Token` to indicate an unclean mapping, and the second element
      /// will be set to the original type returned by `GetType()`.
      ///
      /// This base property class is generic and cannot know ahead of time how to
      /// perform this mapping reliably, thus it will always fall into the second
      /// scenario. It is up to specialized properties to perform the mapping.
      NDR_API
      virtual const SdfTypeIndicator GetTypeAsSdfType() const;
  
      /// @}
  
  protected:
      NdrProperty& operator=(const NdrProperty&) = delete;
  
      TfToken _name;
      TfToken _type;
      VtValue _defaultValue;
      bool _isOutput;
      size_t _arraySize;
      bool _isDynamicArray;
      bool _isConnectable;
      NdrTokenMap _metadata;
  };
  
  PXR_NAMESPACE_CLOSE_SCOPE
  
  #endif // PXR_USD_NDR_PROPERTY_H
  