package policy

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
//
// Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.

import (
	"context"
	"encoding/json"
	"github.com/Azure/go-autorest/autorest"
	"github.com/Azure/go-autorest/autorest/date"
	"github.com/Azure/go-autorest/autorest/to"
	"github.com/Azure/go-autorest/tracing"
	"net/http"
)

// The package's fully qualified name.
const fqdn = "github.com/Azure/azure-sdk-for-go/services/preview/resources/mgmt/2021-06-01-preview/policy"

// Alias the alias type.
type Alias struct {
	// Name - The alias name.
	Name *string `json:"name,omitempty"`
	// Paths - The paths for an alias.
	Paths *[]AliasPath `json:"paths,omitempty"`
	// Type - The type of the alias. Possible values include: 'AliasTypeNotSpecified', 'AliasTypePlainText', 'AliasTypeMask'
	Type AliasType `json:"type,omitempty"`
	// DefaultPath - The default path for an alias.
	DefaultPath *string `json:"defaultPath,omitempty"`
	// DefaultPattern - The default pattern for an alias.
	DefaultPattern *AliasPattern `json:"defaultPattern,omitempty"`
	// DefaultMetadata - READ-ONLY; The default alias path metadata. Applies to the default path and to any alias path that doesn't have metadata
	DefaultMetadata *AliasPathMetadata `json:"defaultMetadata,omitempty"`
}

// MarshalJSON is the custom marshaler for Alias.
func (a Alias) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if a.Name != nil {
		objectMap["name"] = a.Name
	}
	if a.Paths != nil {
		objectMap["paths"] = a.Paths
	}
	if a.Type != "" {
		objectMap["type"] = a.Type
	}
	if a.DefaultPath != nil {
		objectMap["defaultPath"] = a.DefaultPath
	}
	if a.DefaultPattern != nil {
		objectMap["defaultPattern"] = a.DefaultPattern
	}
	return json.Marshal(objectMap)
}

// AliasPath the type of the paths for alias.
type AliasPath struct {
	// Path - The path of an alias.
	Path *string `json:"path,omitempty"`
	// APIVersions - The API versions.
	APIVersions *[]string `json:"apiVersions,omitempty"`
	// Pattern - The pattern for an alias path.
	Pattern *AliasPattern `json:"pattern,omitempty"`
	// Metadata - READ-ONLY; The metadata of the alias path. If missing, fall back to the default metadata of the alias.
	Metadata *AliasPathMetadata `json:"metadata,omitempty"`
}

// MarshalJSON is the custom marshaler for AliasPath.
func (ap AliasPath) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if ap.Path != nil {
		objectMap["path"] = ap.Path
	}
	if ap.APIVersions != nil {
		objectMap["apiVersions"] = ap.APIVersions
	}
	if ap.Pattern != nil {
		objectMap["pattern"] = ap.Pattern
	}
	return json.Marshal(objectMap)
}

// AliasPathMetadata ...
type AliasPathMetadata struct {
	// Type - READ-ONLY; The type of the token that the alias path is referring to. Possible values include: 'AliasPathTokenTypeNotSpecified', 'AliasPathTokenTypeAny', 'AliasPathTokenTypeString', 'AliasPathTokenTypeObject', 'AliasPathTokenTypeArray', 'AliasPathTokenTypeInteger', 'AliasPathTokenTypeNumber', 'AliasPathTokenTypeBoolean'
	Type AliasPathTokenType `json:"type,omitempty"`
	// Attributes - READ-ONLY; The attributes of the token that the alias path is referring to. Possible values include: 'AliasPathAttributesNone', 'AliasPathAttributesModifiable'
	Attributes AliasPathAttributes `json:"attributes,omitempty"`
}

// MarshalJSON is the custom marshaler for AliasPathMetadata.
func (apm AliasPathMetadata) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	return json.Marshal(objectMap)
}

// AliasPattern the type of the pattern for an alias path.
type AliasPattern struct {
	// Phrase - The alias pattern phrase.
	Phrase *string `json:"phrase,omitempty"`
	// Variable - The alias pattern variable.
	Variable *string `json:"variable,omitempty"`
	// Type - The type of alias pattern. Possible values include: 'AliasPatternTypeNotSpecified', 'AliasPatternTypeExtract'
	Type AliasPatternType `json:"type,omitempty"`
}

// Assignment the policy assignment.
type Assignment struct {
	autorest.Response `json:"-"`
	// AssignmentProperties - Properties for the policy assignment.
	*AssignmentProperties `json:"properties,omitempty"`
	// ID - READ-ONLY; The ID of the policy assignment.
	ID *string `json:"id,omitempty"`
	// Type - READ-ONLY; The type of the policy assignment.
	Type *string `json:"type,omitempty"`
	// Name - READ-ONLY; The name of the policy assignment.
	Name *string `json:"name,omitempty"`
	// Location - The location of the policy assignment. Only required when utilizing managed identity.
	Location *string `json:"location,omitempty"`
	// Identity - The managed identity associated with the policy assignment.
	Identity *Identity `json:"identity,omitempty"`
	// SystemData - READ-ONLY; The system metadata relating to this resource.
	SystemData *SystemData `json:"systemData,omitempty"`
}

// MarshalJSON is the custom marshaler for Assignment.
func (a Assignment) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if a.AssignmentProperties != nil {
		objectMap["properties"] = a.AssignmentProperties
	}
	if a.Location != nil {
		objectMap["location"] = a.Location
	}
	if a.Identity != nil {
		objectMap["identity"] = a.Identity
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for Assignment struct.
func (a *Assignment) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "properties":
			if v != nil {
				var assignmentProperties AssignmentProperties
				err = json.Unmarshal(*v, &assignmentProperties)
				if err != nil {
					return err
				}
				a.AssignmentProperties = &assignmentProperties
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				a.ID = &ID
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				a.Type = &typeVar
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				a.Name = &name
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				a.Location = &location
			}
		case "identity":
			if v != nil {
				var identity Identity
				err = json.Unmarshal(*v, &identity)
				if err != nil {
					return err
				}
				a.Identity = &identity
			}
		case "systemData":
			if v != nil {
				var systemData SystemData
				err = json.Unmarshal(*v, &systemData)
				if err != nil {
					return err
				}
				a.SystemData = &systemData
			}
		}
	}

	return nil
}

// AssignmentListResult list of policy assignments.
type AssignmentListResult struct {
	autorest.Response `json:"-"`
	// Value - An array of policy assignments.
	Value *[]Assignment `json:"value,omitempty"`
	// NextLink - The URL to use for getting the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// AssignmentListResultIterator provides access to a complete listing of Assignment values.
type AssignmentListResultIterator struct {
	i    int
	page AssignmentListResultPage
}

// NextWithContext advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
func (iter *AssignmentListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/AssignmentListResultIterator.NextWithContext")
		defer func() {
			sc := -1
			if iter.Response().Response.Response != nil {
				sc = iter.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	iter.i++
	if iter.i < len(iter.page.Values()) {
		return nil
	}
	err = iter.page.NextWithContext(ctx)
	if err != nil {
		iter.i--
		return err
	}
	iter.i = 0
	return nil
}

// Next advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (iter *AssignmentListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter AssignmentListResultIterator) NotDone() bool {
	return iter.page.NotDone() && iter.i < len(iter.page.Values())
}

// Response returns the raw server response from the last page request.
func (iter AssignmentListResultIterator) Response() AssignmentListResult {
	return iter.page.Response()
}

// Value returns the current value or a zero-initialized value if the
// iterator has advanced beyond the end of the collection.
func (iter AssignmentListResultIterator) Value() Assignment {
	if !iter.page.NotDone() {
		return Assignment{}
	}
	return iter.page.Values()[iter.i]
}

// Creates a new instance of the AssignmentListResultIterator type.
func NewAssignmentListResultIterator(page AssignmentListResultPage) AssignmentListResultIterator {
	return AssignmentListResultIterator{page: page}
}

// IsEmpty returns true if the ListResult contains no values.
func (alr AssignmentListResult) IsEmpty() bool {
	return alr.Value == nil || len(*alr.Value) == 0
}

// hasNextLink returns true if the NextLink is not empty.
func (alr AssignmentListResult) hasNextLink() bool {
	return alr.NextLink != nil && len(*alr.NextLink) != 0
}

// assignmentListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (alr AssignmentListResult) assignmentListResultPreparer(ctx context.Context) (*http.Request, error) {
	if !alr.hasNextLink() {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(alr.NextLink)))
}

// AssignmentListResultPage contains a page of Assignment values.
type AssignmentListResultPage struct {
	fn  func(context.Context, AssignmentListResult) (AssignmentListResult, error)
	alr AssignmentListResult
}

// NextWithContext advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
func (page *AssignmentListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/AssignmentListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	for {
		next, err := page.fn(ctx, page.alr)
		if err != nil {
			return err
		}
		page.alr = next
		if !next.hasNextLink() || !next.IsEmpty() {
			break
		}
	}
	return nil
}

// Next advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (page *AssignmentListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

// NotDone returns true if the page enumeration should be started or is not yet complete.
func (page AssignmentListResultPage) NotDone() bool {
	return !page.alr.IsEmpty()
}

// Response returns the raw server response from the last page request.
func (page AssignmentListResultPage) Response() AssignmentListResult {
	return page.alr
}

// Values returns the slice of values for the current page or nil if there are no values.
func (page AssignmentListResultPage) Values() []Assignment {
	if page.alr.IsEmpty() {
		return nil
	}
	return *page.alr.Value
}

// Creates a new instance of the AssignmentListResultPage type.
func NewAssignmentListResultPage(cur AssignmentListResult, getNextPage func(context.Context, AssignmentListResult) (AssignmentListResult, error)) AssignmentListResultPage {
	return AssignmentListResultPage{
		fn:  getNextPage,
		alr: cur,
	}
}

// AssignmentProperties the policy assignment properties.
type AssignmentProperties struct {
	// DisplayName - The display name of the policy assignment.
	DisplayName *string `json:"displayName,omitempty"`
	// PolicyDefinitionID - The ID of the policy definition or policy set definition being assigned.
	PolicyDefinitionID *string `json:"policyDefinitionId,omitempty"`
	// Scope - READ-ONLY; The scope for the policy assignment.
	Scope *string `json:"scope,omitempty"`
	// NotScopes - The policy's excluded scopes.
	NotScopes *[]string `json:"notScopes,omitempty"`
	// Parameters - The parameter values for the assigned policy rule. The keys are the parameter names.
	Parameters map[string]*ParameterValuesValue `json:"parameters"`
	// Description - This message will be part of response in case of policy violation.
	Description *string `json:"description,omitempty"`
	// Metadata - The policy assignment metadata. Metadata is an open ended object and is typically a collection of key value pairs.
	Metadata interface{} `json:"metadata,omitempty"`
	// EnforcementMode - The policy assignment enforcement mode. Possible values are Default and DoNotEnforce. Possible values include: 'EnforcementModeDefault', 'EnforcementModeDoNotEnforce'
	EnforcementMode EnforcementMode `json:"enforcementMode,omitempty"`
	// NonComplianceMessages - The messages that describe why a resource is non-compliant with the policy.
	NonComplianceMessages *[]NonComplianceMessage `json:"nonComplianceMessages,omitempty"`
}

// MarshalJSON is the custom marshaler for AssignmentProperties.
func (ap AssignmentProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if ap.DisplayName != nil {
		objectMap["displayName"] = ap.DisplayName
	}
	if ap.PolicyDefinitionID != nil {
		objectMap["policyDefinitionId"] = ap.PolicyDefinitionID
	}
	if ap.NotScopes != nil {
		objectMap["notScopes"] = ap.NotScopes
	}
	if ap.Parameters != nil {
		objectMap["parameters"] = ap.Parameters
	}
	if ap.Description != nil {
		objectMap["description"] = ap.Description
	}
	if ap.Metadata != nil {
		objectMap["metadata"] = ap.Metadata
	}
	if ap.EnforcementMode != "" {
		objectMap["enforcementMode"] = ap.EnforcementMode
	}
	if ap.NonComplianceMessages != nil {
		objectMap["nonComplianceMessages"] = ap.NonComplianceMessages
	}
	return json.Marshal(objectMap)
}

// AssignmentUpdate ...
type AssignmentUpdate struct {
	// Location - The location of the policy assignment. Only required when utilizing managed identity.
	Location *string `json:"location,omitempty"`
	// Identity - The managed identity associated with the policy assignment.
	Identity *Identity `json:"identity,omitempty"`
}

// CloudError an error response from a policy operation.
type CloudError struct {
	Error *ErrorResponse `json:"error,omitempty"`
}

// DataEffect the data effect definition.
type DataEffect struct {
	// Name - The data effect name.
	Name *string `json:"name,omitempty"`
	// DetailsSchema - The data effect details schema.
	DetailsSchema interface{} `json:"detailsSchema,omitempty"`
}

// DataManifestCustomResourceFunctionDefinition the custom resource function definition.
type DataManifestCustomResourceFunctionDefinition struct {
	// Name - The function name as it will appear in the policy rule. eg - 'vault'.
	Name *string `json:"name,omitempty"`
	// FullyQualifiedResourceType - The fully qualified control plane resource type that this function represents. eg - 'Microsoft.KeyVault/vaults'.
	FullyQualifiedResourceType *string `json:"fullyQualifiedResourceType,omitempty"`
	// DefaultProperties - The top-level properties that can be selected on the function's output. eg - [ "name", "location" ] if vault().name and vault().location are supported
	DefaultProperties *[]string `json:"defaultProperties,omitempty"`
	// AllowCustomProperties - A value indicating whether the custom properties within the property bag are allowed. Needs api-version to be specified in the policy rule eg - vault('2019-06-01').
	AllowCustomProperties *bool `json:"allowCustomProperties,omitempty"`
}

// DataManifestResourceFunctionsDefinition the resource functions supported by a manifest
type DataManifestResourceFunctionsDefinition struct {
	// Standard - The standard resource functions (subscription and/or resourceGroup).
	Standard *[]string `json:"standard,omitempty"`
	// Custom - An array of data manifest custom resource definition.
	Custom *[]DataManifestCustomResourceFunctionDefinition `json:"custom,omitempty"`
}

// DataPolicyManifest the data policy manifest.
type DataPolicyManifest struct {
	autorest.Response `json:"-"`
	// DataPolicyManifestProperties - The data policy manifest properties.
	*DataPolicyManifestProperties `json:"properties,omitempty"`
	// ID - READ-ONLY; The ID of the data policy manifest.
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; The name of the data policy manifest (it's the same as the Policy Mode).
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; The type of the resource (Microsoft.Authorization/dataPolicyManifests).
	Type *string `json:"type,omitempty"`
}

// MarshalJSON is the custom marshaler for DataPolicyManifest.
func (dpm DataPolicyManifest) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if dpm.DataPolicyManifestProperties != nil {
		objectMap["properties"] = dpm.DataPolicyManifestProperties
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for DataPolicyManifest struct.
func (dpm *DataPolicyManifest) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "properties":
			if v != nil {
				var dataPolicyManifestProperties DataPolicyManifestProperties
				err = json.Unmarshal(*v, &dataPolicyManifestProperties)
				if err != nil {
					return err
				}
				dpm.DataPolicyManifestProperties = &dataPolicyManifestProperties
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				dpm.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				dpm.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				dpm.Type = &typeVar
			}
		}
	}

	return nil
}

// DataPolicyManifestListResult list of data policy manifests.
type DataPolicyManifestListResult struct {
	autorest.Response `json:"-"`
	// Value - An array of data policy manifests.
	Value *[]DataPolicyManifest `json:"value,omitempty"`
	// NextLink - The URL to use for getting the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// DataPolicyManifestListResultIterator provides access to a complete listing of DataPolicyManifest values.
type DataPolicyManifestListResultIterator struct {
	i    int
	page DataPolicyManifestListResultPage
}

// NextWithContext advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
func (iter *DataPolicyManifestListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/DataPolicyManifestListResultIterator.NextWithContext")
		defer func() {
			sc := -1
			if iter.Response().Response.Response != nil {
				sc = iter.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	iter.i++
	if iter.i < len(iter.page.Values()) {
		return nil
	}
	err = iter.page.NextWithContext(ctx)
	if err != nil {
		iter.i--
		return err
	}
	iter.i = 0
	return nil
}

// Next advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (iter *DataPolicyManifestListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter DataPolicyManifestListResultIterator) NotDone() bool {
	return iter.page.NotDone() && iter.i < len(iter.page.Values())
}

// Response returns the raw server response from the last page request.
func (iter DataPolicyManifestListResultIterator) Response() DataPolicyManifestListResult {
	return iter.page.Response()
}

// Value returns the current value or a zero-initialized value if the
// iterator has advanced beyond the end of the collection.
func (iter DataPolicyManifestListResultIterator) Value() DataPolicyManifest {
	if !iter.page.NotDone() {
		return DataPolicyManifest{}
	}
	return iter.page.Values()[iter.i]
}

// Creates a new instance of the DataPolicyManifestListResultIterator type.
func NewDataPolicyManifestListResultIterator(page DataPolicyManifestListResultPage) DataPolicyManifestListResultIterator {
	return DataPolicyManifestListResultIterator{page: page}
}

// IsEmpty returns true if the ListResult contains no values.
func (dpmlr DataPolicyManifestListResult) IsEmpty() bool {
	return dpmlr.Value == nil || len(*dpmlr.Value) == 0
}

// hasNextLink returns true if the NextLink is not empty.
func (dpmlr DataPolicyManifestListResult) hasNextLink() bool {
	return dpmlr.NextLink != nil && len(*dpmlr.NextLink) != 0
}

// dataPolicyManifestListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (dpmlr DataPolicyManifestListResult) dataPolicyManifestListResultPreparer(ctx context.Context) (*http.Request, error) {
	if !dpmlr.hasNextLink() {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(dpmlr.NextLink)))
}

// DataPolicyManifestListResultPage contains a page of DataPolicyManifest values.
type DataPolicyManifestListResultPage struct {
	fn    func(context.Context, DataPolicyManifestListResult) (DataPolicyManifestListResult, error)
	dpmlr DataPolicyManifestListResult
}

// NextWithContext advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
func (page *DataPolicyManifestListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/DataPolicyManifestListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	for {
		next, err := page.fn(ctx, page.dpmlr)
		if err != nil {
			return err
		}
		page.dpmlr = next
		if !next.hasNextLink() || !next.IsEmpty() {
			break
		}
	}
	return nil
}

// Next advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (page *DataPolicyManifestListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

// NotDone returns true if the page enumeration should be started or is not yet complete.
func (page DataPolicyManifestListResultPage) NotDone() bool {
	return !page.dpmlr.IsEmpty()
}

// Response returns the raw server response from the last page request.
func (page DataPolicyManifestListResultPage) Response() DataPolicyManifestListResult {
	return page.dpmlr
}

// Values returns the slice of values for the current page or nil if there are no values.
func (page DataPolicyManifestListResultPage) Values() []DataPolicyManifest {
	if page.dpmlr.IsEmpty() {
		return nil
	}
	return *page.dpmlr.Value
}

// Creates a new instance of the DataPolicyManifestListResultPage type.
func NewDataPolicyManifestListResultPage(cur DataPolicyManifestListResult, getNextPage func(context.Context, DataPolicyManifestListResult) (DataPolicyManifestListResult, error)) DataPolicyManifestListResultPage {
	return DataPolicyManifestListResultPage{
		fn:    getNextPage,
		dpmlr: cur,
	}
}

// DataPolicyManifestProperties the properties of the data policy manifest.
type DataPolicyManifestProperties struct {
	// Namespaces - The list of namespaces for the data policy manifest.
	Namespaces *[]string `json:"namespaces,omitempty"`
	// PolicyMode - The policy mode of the data policy manifest.
	PolicyMode *string `json:"policyMode,omitempty"`
	// IsBuiltInOnly - A value indicating whether policy mode is allowed only in built-in definitions.
	IsBuiltInOnly *bool `json:"isBuiltInOnly,omitempty"`
	// ResourceTypeAliases - An array of resource type aliases.
	ResourceTypeAliases *[]ResourceTypeAliases `json:"resourceTypeAliases,omitempty"`
	// Effects - The effect definition.
	Effects *[]DataEffect `json:"effects,omitempty"`
	// FieldValues - The non-alias field accessor values that can be used in the policy rule.
	FieldValues *[]string `json:"fieldValues,omitempty"`
	// DataManifestResourceFunctionsDefinition - The resource functions definition specified in the data manifest.
	*DataManifestResourceFunctionsDefinition `json:"resourceFunctions,omitempty"`
}

// MarshalJSON is the custom marshaler for DataPolicyManifestProperties.
func (dpmp DataPolicyManifestProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if dpmp.Namespaces != nil {
		objectMap["namespaces"] = dpmp.Namespaces
	}
	if dpmp.PolicyMode != nil {
		objectMap["policyMode"] = dpmp.PolicyMode
	}
	if dpmp.IsBuiltInOnly != nil {
		objectMap["isBuiltInOnly"] = dpmp.IsBuiltInOnly
	}
	if dpmp.ResourceTypeAliases != nil {
		objectMap["resourceTypeAliases"] = dpmp.ResourceTypeAliases
	}
	if dpmp.Effects != nil {
		objectMap["effects"] = dpmp.Effects
	}
	if dpmp.FieldValues != nil {
		objectMap["fieldValues"] = dpmp.FieldValues
	}
	if dpmp.DataManifestResourceFunctionsDefinition != nil {
		objectMap["resourceFunctions"] = dpmp.DataManifestResourceFunctionsDefinition
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for DataPolicyManifestProperties struct.
func (dpmp *DataPolicyManifestProperties) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "namespaces":
			if v != nil {
				var namespaces []string
				err = json.Unmarshal(*v, &namespaces)
				if err != nil {
					return err
				}
				dpmp.Namespaces = &namespaces
			}
		case "policyMode":
			if v != nil {
				var policyMode string
				err = json.Unmarshal(*v, &policyMode)
				if err != nil {
					return err
				}
				dpmp.PolicyMode = &policyMode
			}
		case "isBuiltInOnly":
			if v != nil {
				var isBuiltInOnly bool
				err = json.Unmarshal(*v, &isBuiltInOnly)
				if err != nil {
					return err
				}
				dpmp.IsBuiltInOnly = &isBuiltInOnly
			}
		case "resourceTypeAliases":
			if v != nil {
				var resourceTypeAliases []ResourceTypeAliases
				err = json.Unmarshal(*v, &resourceTypeAliases)
				if err != nil {
					return err
				}
				dpmp.ResourceTypeAliases = &resourceTypeAliases
			}
		case "effects":
			if v != nil {
				var effects []DataEffect
				err = json.Unmarshal(*v, &effects)
				if err != nil {
					return err
				}
				dpmp.Effects = &effects
			}
		case "fieldValues":
			if v != nil {
				var fieldValues []string
				err = json.Unmarshal(*v, &fieldValues)
				if err != nil {
					return err
				}
				dpmp.FieldValues = &fieldValues
			}
		case "resourceFunctions":
			if v != nil {
				var dataManifestResourceFunctionsDefinition DataManifestResourceFunctionsDefinition
				err = json.Unmarshal(*v, &dataManifestResourceFunctionsDefinition)
				if err != nil {
					return err
				}
				dpmp.DataManifestResourceFunctionsDefinition = &dataManifestResourceFunctionsDefinition
			}
		}
	}

	return nil
}

// Definition the policy definition.
type Definition struct {
	autorest.Response `json:"-"`
	// DefinitionProperties - The policy definition properties.
	*DefinitionProperties `json:"properties,omitempty"`
	// ID - READ-ONLY; The ID of the policy definition.
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; The name of the policy definition.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; The type of the resource (Microsoft.Authorization/policyDefinitions).
	Type *string `json:"type,omitempty"`
	// SystemData - READ-ONLY; The system metadata relating to this resource.
	SystemData *SystemData `json:"systemData,omitempty"`
}

// MarshalJSON is the custom marshaler for Definition.
func (d Definition) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if d.DefinitionProperties != nil {
		objectMap["properties"] = d.DefinitionProperties
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for Definition struct.
func (d *Definition) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "properties":
			if v != nil {
				var definitionProperties DefinitionProperties
				err = json.Unmarshal(*v, &definitionProperties)
				if err != nil {
					return err
				}
				d.DefinitionProperties = &definitionProperties
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				d.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				d.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				d.Type = &typeVar
			}
		case "systemData":
			if v != nil {
				var systemData SystemData
				err = json.Unmarshal(*v, &systemData)
				if err != nil {
					return err
				}
				d.SystemData = &systemData
			}
		}
	}

	return nil
}

// DefinitionGroup the policy definition group.
type DefinitionGroup struct {
	// Name - The name of the group.
	Name *string `json:"name,omitempty"`
	// DisplayName - The group's display name.
	DisplayName *string `json:"displayName,omitempty"`
	// Category - The group's category.
	Category *string `json:"category,omitempty"`
	// Description - The group's description.
	Description *string `json:"description,omitempty"`
	// AdditionalMetadataID - A resource ID of a resource that contains additional metadata about the group.
	AdditionalMetadataID *string `json:"additionalMetadataId,omitempty"`
}

// DefinitionListResult list of policy definitions.
type DefinitionListResult struct {
	autorest.Response `json:"-"`
	// Value - An array of policy definitions.
	Value *[]Definition `json:"value,omitempty"`
	// NextLink - The URL to use for getting the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// DefinitionListResultIterator provides access to a complete listing of Definition values.
type DefinitionListResultIterator struct {
	i    int
	page DefinitionListResultPage
}

// NextWithContext advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
func (iter *DefinitionListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/DefinitionListResultIterator.NextWithContext")
		defer func() {
			sc := -1
			if iter.Response().Response.Response != nil {
				sc = iter.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	iter.i++
	if iter.i < len(iter.page.Values()) {
		return nil
	}
	err = iter.page.NextWithContext(ctx)
	if err != nil {
		iter.i--
		return err
	}
	iter.i = 0
	return nil
}

// Next advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (iter *DefinitionListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter DefinitionListResultIterator) NotDone() bool {
	return iter.page.NotDone() && iter.i < len(iter.page.Values())
}

// Response returns the raw server response from the last page request.
func (iter DefinitionListResultIterator) Response() DefinitionListResult {
	return iter.page.Response()
}

// Value returns the current value or a zero-initialized value if the
// iterator has advanced beyond the end of the collection.
func (iter DefinitionListResultIterator) Value() Definition {
	if !iter.page.NotDone() {
		return Definition{}
	}
	return iter.page.Values()[iter.i]
}

// Creates a new instance of the DefinitionListResultIterator type.
func NewDefinitionListResultIterator(page DefinitionListResultPage) DefinitionListResultIterator {
	return DefinitionListResultIterator{page: page}
}

// IsEmpty returns true if the ListResult contains no values.
func (dlr DefinitionListResult) IsEmpty() bool {
	return dlr.Value == nil || len(*dlr.Value) == 0
}

// hasNextLink returns true if the NextLink is not empty.
func (dlr DefinitionListResult) hasNextLink() bool {
	return dlr.NextLink != nil && len(*dlr.NextLink) != 0
}

// definitionListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (dlr DefinitionListResult) definitionListResultPreparer(ctx context.Context) (*http.Request, error) {
	if !dlr.hasNextLink() {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(dlr.NextLink)))
}

// DefinitionListResultPage contains a page of Definition values.
type DefinitionListResultPage struct {
	fn  func(context.Context, DefinitionListResult) (DefinitionListResult, error)
	dlr DefinitionListResult
}

// NextWithContext advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
func (page *DefinitionListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/DefinitionListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	for {
		next, err := page.fn(ctx, page.dlr)
		if err != nil {
			return err
		}
		page.dlr = next
		if !next.hasNextLink() || !next.IsEmpty() {
			break
		}
	}
	return nil
}

// Next advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (page *DefinitionListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

// NotDone returns true if the page enumeration should be started or is not yet complete.
func (page DefinitionListResultPage) NotDone() bool {
	return !page.dlr.IsEmpty()
}

// Response returns the raw server response from the last page request.
func (page DefinitionListResultPage) Response() DefinitionListResult {
	return page.dlr
}

// Values returns the slice of values for the current page or nil if there are no values.
func (page DefinitionListResultPage) Values() []Definition {
	if page.dlr.IsEmpty() {
		return nil
	}
	return *page.dlr.Value
}

// Creates a new instance of the DefinitionListResultPage type.
func NewDefinitionListResultPage(cur DefinitionListResult, getNextPage func(context.Context, DefinitionListResult) (DefinitionListResult, error)) DefinitionListResultPage {
	return DefinitionListResultPage{
		fn:  getNextPage,
		dlr: cur,
	}
}

// DefinitionProperties the policy definition properties.
type DefinitionProperties struct {
	// PolicyType - The type of policy definition. Possible values are NotSpecified, BuiltIn, Custom, and Static. Possible values include: 'TypeNotSpecified', 'TypeBuiltIn', 'TypeCustom', 'TypeStatic'
	PolicyType Type `json:"policyType,omitempty"`
	// Mode - The policy definition mode. Some examples are All, Indexed, Microsoft.KeyVault.Data.
	Mode *string `json:"mode,omitempty"`
	// DisplayName - The display name of the policy definition.
	DisplayName *string `json:"displayName,omitempty"`
	// Description - The policy definition description.
	Description *string `json:"description,omitempty"`
	// PolicyRule - The policy rule.
	PolicyRule interface{} `json:"policyRule,omitempty"`
	// Metadata - The policy definition metadata.  Metadata is an open ended object and is typically a collection of key value pairs.
	Metadata interface{} `json:"metadata,omitempty"`
	// Parameters - The parameter definitions for parameters used in the policy rule. The keys are the parameter names.
	Parameters map[string]*ParameterDefinitionsValue `json:"parameters"`
}

// MarshalJSON is the custom marshaler for DefinitionProperties.
func (dp DefinitionProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if dp.PolicyType != "" {
		objectMap["policyType"] = dp.PolicyType
	}
	if dp.Mode != nil {
		objectMap["mode"] = dp.Mode
	}
	if dp.DisplayName != nil {
		objectMap["displayName"] = dp.DisplayName
	}
	if dp.Description != nil {
		objectMap["description"] = dp.Description
	}
	if dp.PolicyRule != nil {
		objectMap["policyRule"] = dp.PolicyRule
	}
	if dp.Metadata != nil {
		objectMap["metadata"] = dp.Metadata
	}
	if dp.Parameters != nil {
		objectMap["parameters"] = dp.Parameters
	}
	return json.Marshal(objectMap)
}

// DefinitionReference the policy definition reference.
type DefinitionReference struct {
	// PolicyDefinitionID - The ID of the policy definition or policy set definition.
	PolicyDefinitionID *string `json:"policyDefinitionId,omitempty"`
	// Parameters - The parameter values for the referenced policy rule. The keys are the parameter names.
	Parameters map[string]*ParameterValuesValue `json:"parameters"`
	// PolicyDefinitionReferenceID - A unique id (within the policy set definition) for this policy definition reference.
	PolicyDefinitionReferenceID *string `json:"policyDefinitionReferenceId,omitempty"`
	// GroupNames - The name of the groups that this policy definition reference belongs to.
	GroupNames *[]string `json:"groupNames,omitempty"`
}

// MarshalJSON is the custom marshaler for DefinitionReference.
func (dr DefinitionReference) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if dr.PolicyDefinitionID != nil {
		objectMap["policyDefinitionId"] = dr.PolicyDefinitionID
	}
	if dr.Parameters != nil {
		objectMap["parameters"] = dr.Parameters
	}
	if dr.PolicyDefinitionReferenceID != nil {
		objectMap["policyDefinitionReferenceId"] = dr.PolicyDefinitionReferenceID
	}
	if dr.GroupNames != nil {
		objectMap["groupNames"] = dr.GroupNames
	}
	return json.Marshal(objectMap)
}

// ErrorAdditionalInfo the resource management error additional info.
type ErrorAdditionalInfo struct {
	// Type - READ-ONLY; The additional info type.
	Type *string `json:"type,omitempty"`
	// Info - READ-ONLY; The additional info.
	Info interface{} `json:"info,omitempty"`
}

// MarshalJSON is the custom marshaler for ErrorAdditionalInfo.
func (eai ErrorAdditionalInfo) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	return json.Marshal(objectMap)
}

// ErrorResponse common error response for all Azure Resource Manager APIs to return error details for
// failed operations. (This also follows the OData error response format.)
type ErrorResponse struct {
	// Code - READ-ONLY; The error code.
	Code *string `json:"code,omitempty"`
	// Message - READ-ONLY; The error message.
	Message *string `json:"message,omitempty"`
	// Target - READ-ONLY; The error target.
	Target *string `json:"target,omitempty"`
	// Details - READ-ONLY; The error details.
	Details *[]ErrorResponse `json:"details,omitempty"`
	// AdditionalInfo - READ-ONLY; The error additional info.
	AdditionalInfo *[]ErrorAdditionalInfo `json:"additionalInfo,omitempty"`
}

// MarshalJSON is the custom marshaler for ErrorResponse.
func (er ErrorResponse) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	return json.Marshal(objectMap)
}

// Exemption the policy exemption.
type Exemption struct {
	autorest.Response `json:"-"`
	// ExemptionProperties - Properties for the policy exemption.
	*ExemptionProperties `json:"properties,omitempty"`
	// SystemData - READ-ONLY; Azure Resource Manager metadata containing createdBy and modifiedBy information.
	SystemData *SystemData `json:"systemData,omitempty"`
	// ID - READ-ONLY; The ID of the policy exemption.
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; The name of the policy exemption.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; The type of the resource (Microsoft.Authorization/policyExemptions).
	Type *string `json:"type,omitempty"`
}

// MarshalJSON is the custom marshaler for Exemption.
func (e Exemption) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if e.ExemptionProperties != nil {
		objectMap["properties"] = e.ExemptionProperties
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for Exemption struct.
func (e *Exemption) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "properties":
			if v != nil {
				var exemptionProperties ExemptionProperties
				err = json.Unmarshal(*v, &exemptionProperties)
				if err != nil {
					return err
				}
				e.ExemptionProperties = &exemptionProperties
			}
		case "systemData":
			if v != nil {
				var systemData SystemData
				err = json.Unmarshal(*v, &systemData)
				if err != nil {
					return err
				}
				e.SystemData = &systemData
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				e.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				e.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				e.Type = &typeVar
			}
		}
	}

	return nil
}

// ExemptionListResult list of policy exemptions.
type ExemptionListResult struct {
	autorest.Response `json:"-"`
	// Value - An array of policy exemptions.
	Value *[]Exemption `json:"value,omitempty"`
	// NextLink - READ-ONLY; The URL to use for getting the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// MarshalJSON is the custom marshaler for ExemptionListResult.
func (elr ExemptionListResult) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if elr.Value != nil {
		objectMap["value"] = elr.Value
	}
	return json.Marshal(objectMap)
}

// ExemptionListResultIterator provides access to a complete listing of Exemption values.
type ExemptionListResultIterator struct {
	i    int
	page ExemptionListResultPage
}

// NextWithContext advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
func (iter *ExemptionListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ExemptionListResultIterator.NextWithContext")
		defer func() {
			sc := -1
			if iter.Response().Response.Response != nil {
				sc = iter.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	iter.i++
	if iter.i < len(iter.page.Values()) {
		return nil
	}
	err = iter.page.NextWithContext(ctx)
	if err != nil {
		iter.i--
		return err
	}
	iter.i = 0
	return nil
}

// Next advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (iter *ExemptionListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter ExemptionListResultIterator) NotDone() bool {
	return iter.page.NotDone() && iter.i < len(iter.page.Values())
}

// Response returns the raw server response from the last page request.
func (iter ExemptionListResultIterator) Response() ExemptionListResult {
	return iter.page.Response()
}

// Value returns the current value or a zero-initialized value if the
// iterator has advanced beyond the end of the collection.
func (iter ExemptionListResultIterator) Value() Exemption {
	if !iter.page.NotDone() {
		return Exemption{}
	}
	return iter.page.Values()[iter.i]
}

// Creates a new instance of the ExemptionListResultIterator type.
func NewExemptionListResultIterator(page ExemptionListResultPage) ExemptionListResultIterator {
	return ExemptionListResultIterator{page: page}
}

// IsEmpty returns true if the ListResult contains no values.
func (elr ExemptionListResult) IsEmpty() bool {
	return elr.Value == nil || len(*elr.Value) == 0
}

// hasNextLink returns true if the NextLink is not empty.
func (elr ExemptionListResult) hasNextLink() bool {
	return elr.NextLink != nil && len(*elr.NextLink) != 0
}

// exemptionListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (elr ExemptionListResult) exemptionListResultPreparer(ctx context.Context) (*http.Request, error) {
	if !elr.hasNextLink() {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(elr.NextLink)))
}

// ExemptionListResultPage contains a page of Exemption values.
type ExemptionListResultPage struct {
	fn  func(context.Context, ExemptionListResult) (ExemptionListResult, error)
	elr ExemptionListResult
}

// NextWithContext advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
func (page *ExemptionListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ExemptionListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	for {
		next, err := page.fn(ctx, page.elr)
		if err != nil {
			return err
		}
		page.elr = next
		if !next.hasNextLink() || !next.IsEmpty() {
			break
		}
	}
	return nil
}

// Next advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (page *ExemptionListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

// NotDone returns true if the page enumeration should be started or is not yet complete.
func (page ExemptionListResultPage) NotDone() bool {
	return !page.elr.IsEmpty()
}

// Response returns the raw server response from the last page request.
func (page ExemptionListResultPage) Response() ExemptionListResult {
	return page.elr
}

// Values returns the slice of values for the current page or nil if there are no values.
func (page ExemptionListResultPage) Values() []Exemption {
	if page.elr.IsEmpty() {
		return nil
	}
	return *page.elr.Value
}

// Creates a new instance of the ExemptionListResultPage type.
func NewExemptionListResultPage(cur ExemptionListResult, getNextPage func(context.Context, ExemptionListResult) (ExemptionListResult, error)) ExemptionListResultPage {
	return ExemptionListResultPage{
		fn:  getNextPage,
		elr: cur,
	}
}

// ExemptionProperties the policy exemption properties.
type ExemptionProperties struct {
	// PolicyAssignmentID - The ID of the policy assignment that is being exempted.
	PolicyAssignmentID *string `json:"policyAssignmentId,omitempty"`
	// PolicyDefinitionReferenceIds - The policy definition reference ID list when the associated policy assignment is an assignment of a policy set definition.
	PolicyDefinitionReferenceIds *[]string `json:"policyDefinitionReferenceIds,omitempty"`
	// ExemptionCategory - The policy exemption category. Possible values are Waiver and Mitigated. Possible values include: 'ExemptionCategoryWaiver', 'ExemptionCategoryMitigated'
	ExemptionCategory ExemptionCategory `json:"exemptionCategory,omitempty"`
	// ExpiresOn - The expiration date and time (in UTC ISO 8601 format yyyy-MM-ddTHH:mm:ssZ) of the policy exemption.
	ExpiresOn *date.Time `json:"expiresOn,omitempty"`
	// DisplayName - The display name of the policy exemption.
	DisplayName *string `json:"displayName,omitempty"`
	// Description - The description of the policy exemption.
	Description *string `json:"description,omitempty"`
	// Metadata - The policy exemption metadata. Metadata is an open ended object and is typically a collection of key value pairs.
	Metadata interface{} `json:"metadata,omitempty"`
}

// Identity identity for the resource.  Policy assignments support a maximum of one identity.  That is
// either a system assigned identity or a single user assigned identity.
type Identity struct {
	// PrincipalID - READ-ONLY; The principal ID of the resource identity.  This property will only be provided for a system assigned identity
	PrincipalID *string `json:"principalId,omitempty"`
	// TenantID - READ-ONLY; The tenant ID of the resource identity.  This property will only be provided for a system assigned identity
	TenantID *string `json:"tenantId,omitempty"`
	// Type - The identity type. This is the only required field when adding a system or user assigned identity to a resource. Possible values include: 'ResourceIdentityTypeSystemAssigned', 'ResourceIdentityTypeUserAssigned', 'ResourceIdentityTypeNone'
	Type ResourceIdentityType `json:"type,omitempty"`
	// UserAssignedIdentities - The user identity associated with the policy. The user identity dictionary key references will be ARM resource ids in the form: '/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName}'.
	UserAssignedIdentities map[string]*IdentityUserAssignedIdentitiesValue `json:"userAssignedIdentities"`
}

// MarshalJSON is the custom marshaler for Identity.
func (i Identity) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if i.Type != "" {
		objectMap["type"] = i.Type
	}
	if i.UserAssignedIdentities != nil {
		objectMap["userAssignedIdentities"] = i.UserAssignedIdentities
	}
	return json.Marshal(objectMap)
}

// IdentityUserAssignedIdentitiesValue ...
type IdentityUserAssignedIdentitiesValue struct {
	// PrincipalID - READ-ONLY; The principal id of user assigned identity.
	PrincipalID *string `json:"principalId,omitempty"`
	// ClientID - READ-ONLY; The client id of user assigned identity.
	ClientID *string `json:"clientId,omitempty"`
}

// MarshalJSON is the custom marshaler for IdentityUserAssignedIdentitiesValue.
func (iAiv IdentityUserAssignedIdentitiesValue) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	return json.Marshal(objectMap)
}

// NonComplianceMessage a message that describes why a resource is non-compliant with the policy. This is
// shown in 'deny' error messages and on resource's non-compliant compliance results.
type NonComplianceMessage struct {
	// Message - A message that describes why a resource is non-compliant with the policy. This is shown in 'deny' error messages and on resource's non-compliant compliance results.
	Message *string `json:"message,omitempty"`
	// PolicyDefinitionReferenceID - The policy definition reference ID within a policy set definition the message is intended for. This is only applicable if the policy assignment assigns a policy set definition. If this is not provided the message applies to all policies assigned by this policy assignment.
	PolicyDefinitionReferenceID *string `json:"policyDefinitionReferenceId,omitempty"`
}

// ParameterDefinitionsValue the definition of a parameter that can be provided to the policy.
type ParameterDefinitionsValue struct {
	// Type - The data type of the parameter. Possible values include: 'ParameterTypeString', 'ParameterTypeArray', 'ParameterTypeObject', 'ParameterTypeBoolean', 'ParameterTypeInteger', 'ParameterTypeFloat', 'ParameterTypeDateTime'
	Type ParameterType `json:"type,omitempty"`
	// AllowedValues - The allowed values for the parameter.
	AllowedValues *[]interface{} `json:"allowedValues,omitempty"`
	// DefaultValue - The default value for the parameter if no value is provided.
	DefaultValue interface{} `json:"defaultValue,omitempty"`
	// Metadata - General metadata for the parameter.
	Metadata *ParameterDefinitionsValueMetadata `json:"metadata,omitempty"`
}

// ParameterDefinitionsValueMetadata general metadata for the parameter.
type ParameterDefinitionsValueMetadata struct {
	// AdditionalProperties - Unmatched properties from the message are deserialized this collection
	AdditionalProperties map[string]interface{} `json:""`
	// DisplayName - The display name for the parameter.
	DisplayName *string `json:"displayName,omitempty"`
	// Description - The description of the parameter.
	Description *string `json:"description,omitempty"`
	// StrongType - Used when assigning the policy definition through the portal. Provides a context aware list of values for the user to choose from.
	StrongType *string `json:"strongType,omitempty"`
	// AssignPermissions - Set to true to have Azure portal create role assignments on the resource ID or resource scope value of this parameter during policy assignment. This property is useful in case you wish to assign permissions outside the assignment scope.
	AssignPermissions *bool `json:"assignPermissions,omitempty"`
}

// MarshalJSON is the custom marshaler for ParameterDefinitionsValueMetadata.
func (pdv ParameterDefinitionsValueMetadata) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if pdv.DisplayName != nil {
		objectMap["displayName"] = pdv.DisplayName
	}
	if pdv.Description != nil {
		objectMap["description"] = pdv.Description
	}
	if pdv.StrongType != nil {
		objectMap["strongType"] = pdv.StrongType
	}
	if pdv.AssignPermissions != nil {
		objectMap["assignPermissions"] = pdv.AssignPermissions
	}
	for k, v := range pdv.AdditionalProperties {
		objectMap[k] = v
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ParameterDefinitionsValueMetadata struct.
func (pdv *ParameterDefinitionsValueMetadata) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		default:
			if v != nil {
				var additionalProperties interface{}
				err = json.Unmarshal(*v, &additionalProperties)
				if err != nil {
					return err
				}
				if pdv.AdditionalProperties == nil {
					pdv.AdditionalProperties = make(map[string]interface{})
				}
				pdv.AdditionalProperties[k] = additionalProperties
			}
		case "displayName":
			if v != nil {
				var displayName string
				err = json.Unmarshal(*v, &displayName)
				if err != nil {
					return err
				}
				pdv.DisplayName = &displayName
			}
		case "description":
			if v != nil {
				var description string
				err = json.Unmarshal(*v, &description)
				if err != nil {
					return err
				}
				pdv.Description = &description
			}
		case "strongType":
			if v != nil {
				var strongType string
				err = json.Unmarshal(*v, &strongType)
				if err != nil {
					return err
				}
				pdv.StrongType = &strongType
			}
		case "assignPermissions":
			if v != nil {
				var assignPermissions bool
				err = json.Unmarshal(*v, &assignPermissions)
				if err != nil {
					return err
				}
				pdv.AssignPermissions = &assignPermissions
			}
		}
	}

	return nil
}

// ParameterValuesValue the value of a parameter.
type ParameterValuesValue struct {
	// Value - The value of the parameter.
	Value interface{} `json:"value,omitempty"`
}

// ResourceTypeAliases the resource type aliases definition.
type ResourceTypeAliases struct {
	// ResourceType - The resource type name.
	ResourceType *string `json:"resourceType,omitempty"`
	// Aliases - The aliases for property names.
	Aliases *[]Alias `json:"aliases,omitempty"`
}

// SetDefinition the policy set definition.
type SetDefinition struct {
	autorest.Response `json:"-"`
	// SetDefinitionProperties - The policy definition properties.
	*SetDefinitionProperties `json:"properties,omitempty"`
	// ID - READ-ONLY; The ID of the policy set definition.
	ID *string `json:"id,omitempty"`
	// Name - READ-ONLY; The name of the policy set definition.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; The type of the resource (Microsoft.Authorization/policySetDefinitions).
	Type *string `json:"type,omitempty"`
	// SystemData - READ-ONLY; The system metadata relating to this resource.
	SystemData *SystemData `json:"systemData,omitempty"`
}

// MarshalJSON is the custom marshaler for SetDefinition.
func (sd SetDefinition) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if sd.SetDefinitionProperties != nil {
		objectMap["properties"] = sd.SetDefinitionProperties
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for SetDefinition struct.
func (sd *SetDefinition) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "properties":
			if v != nil {
				var setDefinitionProperties SetDefinitionProperties
				err = json.Unmarshal(*v, &setDefinitionProperties)
				if err != nil {
					return err
				}
				sd.SetDefinitionProperties = &setDefinitionProperties
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				sd.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				sd.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				sd.Type = &typeVar
			}
		case "systemData":
			if v != nil {
				var systemData SystemData
				err = json.Unmarshal(*v, &systemData)
				if err != nil {
					return err
				}
				sd.SystemData = &systemData
			}
		}
	}

	return nil
}

// SetDefinitionListResult list of policy set definitions.
type SetDefinitionListResult struct {
	autorest.Response `json:"-"`
	// Value - An array of policy set definitions.
	Value *[]SetDefinition `json:"value,omitempty"`
	// NextLink - The URL to use for getting the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// SetDefinitionListResultIterator provides access to a complete listing of SetDefinition values.
type SetDefinitionListResultIterator struct {
	i    int
	page SetDefinitionListResultPage
}

// NextWithContext advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
func (iter *SetDefinitionListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/SetDefinitionListResultIterator.NextWithContext")
		defer func() {
			sc := -1
			if iter.Response().Response.Response != nil {
				sc = iter.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	iter.i++
	if iter.i < len(iter.page.Values()) {
		return nil
	}
	err = iter.page.NextWithContext(ctx)
	if err != nil {
		iter.i--
		return err
	}
	iter.i = 0
	return nil
}

// Next advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (iter *SetDefinitionListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter SetDefinitionListResultIterator) NotDone() bool {
	return iter.page.NotDone() && iter.i < len(iter.page.Values())
}

// Response returns the raw server response from the last page request.
func (iter SetDefinitionListResultIterator) Response() SetDefinitionListResult {
	return iter.page.Response()
}

// Value returns the current value or a zero-initialized value if the
// iterator has advanced beyond the end of the collection.
func (iter SetDefinitionListResultIterator) Value() SetDefinition {
	if !iter.page.NotDone() {
		return SetDefinition{}
	}
	return iter.page.Values()[iter.i]
}

// Creates a new instance of the SetDefinitionListResultIterator type.
func NewSetDefinitionListResultIterator(page SetDefinitionListResultPage) SetDefinitionListResultIterator {
	return SetDefinitionListResultIterator{page: page}
}

// IsEmpty returns true if the ListResult contains no values.
func (sdlr SetDefinitionListResult) IsEmpty() bool {
	return sdlr.Value == nil || len(*sdlr.Value) == 0
}

// hasNextLink returns true if the NextLink is not empty.
func (sdlr SetDefinitionListResult) hasNextLink() bool {
	return sdlr.NextLink != nil && len(*sdlr.NextLink) != 0
}

// setDefinitionListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (sdlr SetDefinitionListResult) setDefinitionListResultPreparer(ctx context.Context) (*http.Request, error) {
	if !sdlr.hasNextLink() {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(sdlr.NextLink)))
}

// SetDefinitionListResultPage contains a page of SetDefinition values.
type SetDefinitionListResultPage struct {
	fn   func(context.Context, SetDefinitionListResult) (SetDefinitionListResult, error)
	sdlr SetDefinitionListResult
}

// NextWithContext advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
func (page *SetDefinitionListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/SetDefinitionListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	for {
		next, err := page.fn(ctx, page.sdlr)
		if err != nil {
			return err
		}
		page.sdlr = next
		if !next.hasNextLink() || !next.IsEmpty() {
			break
		}
	}
	return nil
}

// Next advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (page *SetDefinitionListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

// NotDone returns true if the page enumeration should be started or is not yet complete.
func (page SetDefinitionListResultPage) NotDone() bool {
	return !page.sdlr.IsEmpty()
}

// Response returns the raw server response from the last page request.
func (page SetDefinitionListResultPage) Response() SetDefinitionListResult {
	return page.sdlr
}

// Values returns the slice of values for the current page or nil if there are no values.
func (page SetDefinitionListResultPage) Values() []SetDefinition {
	if page.sdlr.IsEmpty() {
		return nil
	}
	return *page.sdlr.Value
}

// Creates a new instance of the SetDefinitionListResultPage type.
func NewSetDefinitionListResultPage(cur SetDefinitionListResult, getNextPage func(context.Context, SetDefinitionListResult) (SetDefinitionListResult, error)) SetDefinitionListResultPage {
	return SetDefinitionListResultPage{
		fn:   getNextPage,
		sdlr: cur,
	}
}

// SetDefinitionProperties the policy set definition properties.
type SetDefinitionProperties struct {
	// PolicyType - The type of policy definition. Possible values are NotSpecified, BuiltIn, Custom, and Static. Possible values include: 'TypeNotSpecified', 'TypeBuiltIn', 'TypeCustom', 'TypeStatic'
	PolicyType Type `json:"policyType,omitempty"`
	// DisplayName - The display name of the policy set definition.
	DisplayName *string `json:"displayName,omitempty"`
	// Description - The policy set definition description.
	Description *string `json:"description,omitempty"`
	// Metadata - The policy set definition metadata.  Metadata is an open ended object and is typically a collection of key value pairs.
	Metadata interface{} `json:"metadata,omitempty"`
	// Parameters - The policy set definition parameters that can be used in policy definition references.
	Parameters map[string]*ParameterDefinitionsValue `json:"parameters"`
	// PolicyDefinitions - An array of policy definition references.
	PolicyDefinitions *[]DefinitionReference `json:"policyDefinitions,omitempty"`
	// PolicyDefinitionGroups - The metadata describing groups of policy definition references within the policy set definition.
	PolicyDefinitionGroups *[]DefinitionGroup `json:"policyDefinitionGroups,omitempty"`
}

// MarshalJSON is the custom marshaler for SetDefinitionProperties.
func (sdp SetDefinitionProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if sdp.PolicyType != "" {
		objectMap["policyType"] = sdp.PolicyType
	}
	if sdp.DisplayName != nil {
		objectMap["displayName"] = sdp.DisplayName
	}
	if sdp.Description != nil {
		objectMap["description"] = sdp.Description
	}
	if sdp.Metadata != nil {
		objectMap["metadata"] = sdp.Metadata
	}
	if sdp.Parameters != nil {
		objectMap["parameters"] = sdp.Parameters
	}
	if sdp.PolicyDefinitions != nil {
		objectMap["policyDefinitions"] = sdp.PolicyDefinitions
	}
	if sdp.PolicyDefinitionGroups != nil {
		objectMap["policyDefinitionGroups"] = sdp.PolicyDefinitionGroups
	}
	return json.Marshal(objectMap)
}

// SystemData metadata pertaining to creation and last modification of the resource.
type SystemData struct {
	// CreatedBy - The identity that created the resource.
	CreatedBy *string `json:"createdBy,omitempty"`
	// CreatedByType - The type of identity that created the resource. Possible values include: 'CreatedByTypeUser', 'CreatedByTypeApplication', 'CreatedByTypeManagedIdentity', 'CreatedByTypeKey'
	CreatedByType CreatedByType `json:"createdByType,omitempty"`
	// CreatedAt - The timestamp of resource creation (UTC).
	CreatedAt *date.Time `json:"createdAt,omitempty"`
	// LastModifiedBy - The identity that last modified the resource.
	LastModifiedBy *string `json:"lastModifiedBy,omitempty"`
	// LastModifiedByType - The type of identity that last modified the resource. Possible values include: 'CreatedByTypeUser', 'CreatedByTypeApplication', 'CreatedByTypeManagedIdentity', 'CreatedByTypeKey'
	LastModifiedByType CreatedByType `json:"lastModifiedByType,omitempty"`
	// LastModifiedAt - The timestamp of resource last modification (UTC)
	LastModifiedAt *date.Time `json:"lastModifiedAt,omitempty"`
}
