//
// Copyright 2023 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://openusd.org/license.
//
////////////////////////////////////////////////////////////////////////

/* ************************************************************************** */
/* **                                                                      ** */
/* ** This file is generated by a script.                                  ** */
/* **                                                                      ** */
/* ** Do not edit it directly (unless it is within a CUSTOM CODE section)! ** */
/* ** Edit hdSchemaDefs.py instead to make changes.                        ** */
/* **                                                                      ** */
/* ************************************************************************** */

#ifndef {{ HEADER_GUARD|snake }}_{{ FILE_NAME|snake }}_H
#define {{ HEADER_GUARD|snake }}_{{ FILE_NAME|snake }}_H

/// \file
{% if LIBRARY_API %}
#include "{{ INCLUDE_PATH }}/api.h"
{%- endif -%}

{%- if SCHEMA_INCLUDES is defined -%}
{% for t in SCHEMA_INCLUDES %}
#include "{{ t | expand }}.h"
{%- endfor -%}
{%- endif %}

#include "pxr/imaging/hd/schema.h"
{%- if VERSION_GUARD_CONST_GETTER %}
#include "pxr/imaging/hd/version.h"
{%- endif %}

// --(BEGIN CUSTOM CODE: Includes)--
{%- if 'Includes' in CUSTOM_CODE_HEADER %}
{{ CUSTOM_CODE_HEADER['Includes'] }}
{%- endif %}
// --(END CUSTOM CODE: Includes)--

PXR_NAMESPACE_OPEN_SCOPE

// --(BEGIN CUSTOM CODE: Declares)--
{%- if 'Declares' in CUSTOM_CODE_HEADER %}
{{ CUSTOM_CODE_HEADER['Declares'] }}
{%- endif %}
// --(END CUSTOM CODE: Declares)--

#define {{ SCHEMA_CLASS_NAME|snake }}_TOKENS \

{%- if SCHEMA_TOKEN is defined %}
    ({{SCHEMA_TOKEN}}) \
{%- endif -%}

{%- if MEMBERS is defined -%}
{%- for name, type_name, opt_dict in MEMBERS -%}
{%- if SCHEMA_TOKEN is not defined or name != SCHEMA_TOKEN %}
    ({{name}}) \
{%- endif -%}
{%- endfor -%}
{%- endif -%}

{%- if EXTRA_TOKENS is defined -%}
{%- for t in EXTRA_TOKENS %}
    ({{t}}) \
{%- endfor -%}
{%- endif -%}

{%- if STATIC_TOKEN_DATASOURCE_BUILDERS is defined -%}
{%- for typeName, tokens in STATIC_TOKEN_DATASOURCE_BUILDERS -%}
{%- for token in tokens %}
    ({{token}}) \
{%- endfor -%}
{%- endfor -%}
{%- endif %}

TF_DECLARE_PUBLIC_TOKENS({{SCHEMA_CLASS_NAME}}Tokens,{% if LIBRARY_API%} {{ LIBRARY_API }},{% endif %}
    {{ SCHEMA_CLASS_NAME|snake }}_TOKENS);

//-----------------------------------------------------------------------------

{% if DOC is defined -%}
{{ DOC | expand | makeComment }}
{%- endif %}
class {{ SCHEMA_CLASS_NAME }} : public HdSchema
{
public:
    /// \name Schema retrieval
    /// @{

    {{ SCHEMA_CLASS_NAME }}(HdContainerDataSourceHandle container)
      : HdSchema(container) {}

{%- if SCHEMA_TOKEN is defined %}

    /// Retrieves a container data source with the schema's default name token
    /// "{{ SCHEMA_TOKEN }}" from the parent container and constructs a
    /// {{SCHEMA_CLASS_NAME}} instance.
    /// Because the requested container data source may not exist, the result
    /// should be checked with IsDefined() or a bool comparison before use.
    {{ LIBRARY_API }}
    static {{ SCHEMA_CLASS_NAME }} GetFromParent(
        const HdContainerDataSourceHandle &fromParentContainer);
{%- endif %}

    /// @}

// --(BEGIN CUSTOM CODE: Schema Methods)--
{%- if 'Schema Methods' in CUSTOM_CODE_HEADER %}
{{ CUSTOM_CODE_HEADER['Schema Methods'] }}
{%- endif %}
// --(END CUSTOM CODE: Schema Methods)--

    /// \name Member accessor
    /// @{
{%- if GENERIC_MEMBER is defined -%}
{%- set name, type_name, opt_dict = GENERIC_MEMBER -%}
{%- if opt_dict.get('GETTER', True) %}

    {{ LIBRARY_API }}
    TfTokenVector Get{{ name | capitalizeFirst }}Names()
{%- if VERSION_GUARD_CONST_GETTER %}
#if HD_API_VERSION >= 66
                                            const;
#else
                                                 ;
#endif
{% else %} const;
{% endif -%} {# if VERSION_GUARD_CONST_GETTER #}

{%- if 'DOC' in opt_dict -%}
{%- for l in (opt_dict['DOC'].split()|join(' ')|wordwrap(width=70)).split('\n') %}
    /// {{l}}
{%- endfor -%}
{%- endif %}
    {{ LIBRARY_API }}
    {{ type_name}}{% if not type_name.endswith('Schema') %}Handle{% endif %} Get{{ name|capitalizeFirst }}(const TfToken &name)
{%- if VERSION_GUARD_CONST_GETTER %}
#if HD_API_VERSION >= 66
                                            const;
#else
                                                 ;
#endif
{% else %} const;
{%- endif -%} {# if VERSION_GUARD_CONST_GETTER #}
{%- endif -%} {# if opt_dict.get('GETTER', True) #}
{%- endif -%} {# if GENERIC_MEMBER is defined #}

{%- if MEMBERS is defined -%}
{%- for name, type_name, opt_dict in MEMBERS -%}
{%- if opt_dict.get('GETTER', True) %}
{% if 'DOC' in opt_dict -%}
{%- for l in (opt_dict['DOC'].split()|join(' ')|wordwrap(width=70)).split('\n') %}
    /// {{l}}
{%- endfor -%}
{%- endif %}
    {{ LIBRARY_API }}
    {{ type_name}}{% if not type_name.endswith('Schema') %}Handle{% endif %} Get{{ name|capitalizeFirst }}()
{%- if VERSION_GUARD_CONST_GETTER %}
#if HD_API_VERSION >= 66
                                            const;
#else
                                                 ;
#endif
{% else %} const;
{%- endif -%} {# if VERSION_GUARD_CONST_GETTER #}
{%- endif -%} {# if opt_dict.get('GETTER', True) #}
{%- endfor -%}
{%- endif %} {# if MEMBERS is defined #}

    /// @}

{%- if SCHEMA_TOKEN is defined %}

    /// \name Schema location
    /// @{

    /// Returns a token where the container representing this schema is found in
    /// a container by default.
    {{ LIBRARY_API }}
    static const TfToken &GetSchemaToken();

{%- if ADD_DEFAULT_LOCATOR is defined %}

    /// Returns an HdDataSourceLocator (relative to the prim-level data source)
    /// where the container representing this schema is found by default.
    {{ LIBRARY_API }}
    static const HdDataSourceLocator &GetDefaultLocator();
{%- endif %}

    /// @}
{%- endif -%}


{%- if self.member_locators() | trim %}

    /// \name Data source locators for members
    ///
    /// The following methods return an HdDataSourceLocator (relative to the
    /// prim-level data source) where the data source for a member can be found.
    ///
    /// This is often useful for checking intersection against the
    /// HdDataSourceLocatorSet sent with HdDataSourceObserver::PrimsDirtied.
    /// @{

{%- block member_locators -%}
{%- if MEMBERS is defined -%}
{%- for name, type_name, opt_dict in MEMBERS -%}
{%- if opt_dict['ADD_LOCATOR'] %}

    /// Prim-level relative data source locator to locate {{ name }}.
    {{ LIBRARY_API }}
    static const HdDataSourceLocator &Get{{ name |capitalizeFirst  }}Locator();
{%- endif -%}
{%- endfor -%}
{%- endif -%} {# if MEMBERS is defined #}

{%- if STATIC_LOCATOR_ACCESSORS is defined -%}
{%- for name, tokens in STATIC_LOCATOR_ACCESSORS %}

    /// Additional prim-level relative data source locator to locate
    /// {{ name }}.
    {{ LIBRARY_API }}
    static const HdDataSourceLocator &Get{{name | capitalizeFirst}}Locator();
{%- endfor -%}
{%- endif -%}
{%- endblock member_locators %}
    /// @}
{%- endif %} {# if self.member_locators() | trim #}

    /// \name Schema construction
    /// @{

{%- if GENERIC_MEMBER is defined %}
    {{ LIBRARY_API }}
    static HdContainerDataSourceHandle
    BuildRetained(
        size_t count,
        const TfToken *names,
        const HdDataSourceBaseHandle *values);
{%- else -%}
{%- if MEMBERS %}

    /// \deprecated Use Builder instead.
    ///
    /// Builds a container data source which includes the provided child data
    /// sources. Parameters with nullptr values are excluded. This is a
    /// low-level interface. For cases in which it's desired to define
    /// the container with a sparse set of child fields, the Builder class
    /// is often more convenient and readable.
    {{ LIBRARY_API }}
    static HdContainerDataSourceHandle
    BuildRetained(
{%- for name, type_name, opt_dict in MEMBERS %}
        const {{ type_name | underlyingDataSource }}Handle &{{ name }}{%if loop.last == False %},{% endif -%}
{%- endfor %}
    );

    /// \class {{ SCHEMA_CLASS_NAME }}::Builder
    /// 
    /// Utility class for setting sparse sets of child data source fields to be
    /// filled as arguments into BuildRetained. Because all setter methods
    /// return a reference to the instance, this can be used in the "builder
    /// pattern" form.
    class Builder
    {
    public:
{%- for name, type_name, opt_dict in MEMBERS %}
        {{ LIBRARY_API }}
        Builder &Set{{ name|capitalizeFirst }}(
            const {{ type_name | underlyingDataSource}}Handle &{{name}});
{%- endfor %}

        /// Returns a container data source containing the members set thus far.
        {{ LIBRARY_API }}
        HdContainerDataSourceHandle Build();

    private:
{%- for name, type_name, opt_dict in MEMBERS %}
        {{ type_name | underlyingDataSource}}Handle _{{name}};
{%- endfor %}

    };
{%- endif -%} {# else of if MEMBERS #}
{%- endif -%} {# else of if GENERIC_MEMBER is defined #}

{%- if STATIC_TOKEN_DATASOURCE_BUILDERS is defined -%}
{%- for typeName, tokens in STATIC_TOKEN_DATASOURCE_BUILDERS %}

    /// Returns token data source for use as {{typeName}} value.
    ///
    /// The following values will be stored statically and reused for future
    /// calls:
{%- for token in tokens %}
    /// - {{SCHEMA_CLASS_NAME}}Tokens->{{ token | tokenName }}
{%- endfor %}
    {{ LIBRARY_API }}
    static HdTokenDataSourceHandle Build{{typeName|capitalizeFirst}}DataSource(
        const TfToken &{{typeName}});
{%- endfor -%}
{%- endif %}

    /// @}
};

PXR_NAMESPACE_CLOSE_SCOPE

#endif
