// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file was auto-generated by the vanadium vdl tool.
// Package: signing

package signing

import (
	"fmt"
	"v.io/v23/security"
	"v.io/v23/vdl"
)

var _ = __VDLInit() // Must be first; see __VDLInit comments for details.

//////////////////////////////////////////////////
// Type definitions

type (
	// Item represents any single field of the Item union type.
	//
	// An Item represents either a marshalled data item or its SHA-256 hash.
	// The Data field is a []byte, rather than an "any" to make signatures
	// determistic.  VOM encoding is not deterministic for two reasons:
	// - map elements may be marshalled in any order
	// - different versions of VOM may marshal in different ways.
	// Thus, the initial producer of a data item marshals the data once, and it is
	// this marshalled form that is transmitted from device to device.  If the
	// data were unmarshalled and then remarsahalled, the signatures might not
	// match.  The Hash field is used instead of the Data field when the recipient
	// of the DataWithSignature is not permitted to see certain Items' Data
	// fields.
	Item interface {
		// Index returns the field index.
		Index() int
		// Interface returns the field value as an interface.
		Interface() interface{}
		// Name returns the field name.
		Name() string
		// __VDLReflect describes the Item union type.
		__VDLReflect(__ItemReflect)
		VDLIsZero() bool
		VDLWrite(vdl.Encoder) error
	}
	// ItemData represents field Data of the Item union type.
	ItemData struct{ Value []byte } // Marshalled form of data.
	// ItemHash represents field Hash of the Item union type.
	ItemHash struct{ Value []byte } // Hash of what would have been in Data, as returned by SumByteVectorWithLength(Data).
	// __ItemReflect describes the Item union type.
	__ItemReflect struct {
		Name  string `vdl:"v.io/x/ref/services/syncbase/signing.Item"`
		Type  Item
		Union struct {
			Data ItemData
			Hash ItemHash
		}
	}
)

func (x ItemData) Index() int                 { return 0 }
func (x ItemData) Interface() interface{}     { return x.Value }
func (x ItemData) Name() string               { return "Data" }
func (x ItemData) __VDLReflect(__ItemReflect) {}

func (x ItemHash) Index() int                 { return 1 }
func (x ItemHash) Interface() interface{}     { return x.Value }
func (x ItemHash) Name() string               { return "Hash" }
func (x ItemHash) __VDLReflect(__ItemReflect) {}

func (x ItemData) VDLIsZero() bool {
	return len(x.Value) == 0
}

func (x ItemHash) VDLIsZero() bool {
	return false
}

func (x ItemData) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_2); err != nil {
		return err
	}
	if err := enc.NextFieldValueBytes(0, __VDLType_list_1, x.Value); err != nil {
		return err
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x ItemHash) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_union_2); err != nil {
		return err
	}
	if err := enc.NextFieldValueBytes(1, __VDLType_list_1, x.Value); err != nil {
		return err
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func VDLReadItem(dec vdl.Decoder, x *Item) error {
	if err := dec.StartValue(__VDLType_union_2); err != nil {
		return err
	}
	decType := dec.Type()
	index, err := dec.NextField()
	switch {
	case err != nil:
		return err
	case index == -1:
		return fmt.Errorf("missing field in union %T, from %v", x, decType)
	}
	if decType != __VDLType_union_2 {
		name := decType.Field(index).Name
		index = __VDLType_union_2.FieldIndexByName(name)
		if index == -1 {
			return fmt.Errorf("field %q not in union %T, from %v", name, x, decType)
		}
	}
	switch index {
	case 0:
		var field ItemData
		if err := dec.ReadValueBytes(-1, &field.Value); err != nil {
			return err
		}
		*x = field
	case 1:
		var field ItemHash
		if err := dec.ReadValueBytes(-1, &field.Value); err != nil {
			return err
		}
		*x = field
	}
	switch index, err := dec.NextField(); {
	case err != nil:
		return err
	case index != -1:
		return fmt.Errorf("extra field %d in union %T, from %v", index, x, dec.Type())
	}
	return dec.FinishValue()
}

// A DataWithSignature represents a signed, and possibily validated, collection
// of Item structs.
//
// If IsValidated==false and the AuthorSigned signature is valid, it means:
//    The signer whose Blessings have hash BlessingsHash asserts Data.
//
// If IsValidated==true and both AuthorSigned and ValidatorSigned signatures are is valid,
// it means both:
// 1) The signer whose Blessings b have hash BlessingsHash asserts Data.
// 2) If vd is the ValidatorData with hash ValidatorDataHash, the owner of
//    vd.PublicKey asserts that it checked that at least the names vd.Names[] were
//    valid in b.
//
// The sender obtains:
// - BlessingsHash (and the wire form of the blessings) with ValidationCache.AddBlessings().
// - ValidatorDataHash (and the wire form of the ValidataData)  with ValidationCache.AddValidatorData().
//
// The receiver looks up:
// - BlessingsHash with ValidationCache.LookupBlessingsData()
// - ValidatorDataHash with ValidationCache.LookupValidatorData()
//
// If not yet there, the receiver inserts the valus into its ValidationCache with:
// - ValidationCache.AddWireBlessings()
// - ValidationCache.AddValidatorData()
type DataWithSignature struct {
	Data []Item
	// BlessingsHash is a key for the validation cache; the corresponding
	// cached value is a security.Blessings.
	BlessingsHash []byte
	// AuthorSigned is the signature of Data and BlessingsHash using the
	// private key associated with the blessings hashed in BlessingsHash.
	AuthorSigned security.Signature
	IsValidated  bool // Whether fields below are meaningful.
	// ValidatorDataHash is a key for the validation cache returned by
	// ValidatorData.Hash(); the corresponding cached value is the
	// ValidatorData.
	ValidatorDataHash []byte
	ValidatorSigned   security.Signature
}

func (DataWithSignature) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/services/syncbase/signing.DataWithSignature"`
}) {
}

func (x DataWithSignature) VDLIsZero() bool {
	if len(x.Data) != 0 {
		return false
	}
	if len(x.BlessingsHash) != 0 {
		return false
	}
	if !x.AuthorSigned.VDLIsZero() {
		return false
	}
	if x.IsValidated {
		return false
	}
	if len(x.ValidatorDataHash) != 0 {
		return false
	}
	if !x.ValidatorSigned.VDLIsZero() {
		return false
	}
	return true
}

func (x DataWithSignature) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_3); err != nil {
		return err
	}
	if len(x.Data) != 0 {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_1(enc, x.Data); err != nil {
			return err
		}
	}
	if len(x.BlessingsHash) != 0 {
		if err := enc.NextFieldValueBytes(1, __VDLType_list_1, x.BlessingsHash); err != nil {
			return err
		}
	}
	if !x.AuthorSigned.VDLIsZero() {
		if err := enc.NextField(2); err != nil {
			return err
		}
		if err := x.AuthorSigned.VDLWrite(enc); err != nil {
			return err
		}
	}
	if x.IsValidated {
		if err := enc.NextFieldValueBool(3, vdl.BoolType, x.IsValidated); err != nil {
			return err
		}
	}
	if len(x.ValidatorDataHash) != 0 {
		if err := enc.NextFieldValueBytes(4, __VDLType_list_1, x.ValidatorDataHash); err != nil {
			return err
		}
	}
	if !x.ValidatorSigned.VDLIsZero() {
		if err := enc.NextField(5); err != nil {
			return err
		}
		if err := x.ValidatorSigned.VDLWrite(enc); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_1(enc vdl.Encoder, x []Item) error {
	if err := enc.StartValue(__VDLType_list_4); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for _, elem := range x {
		if err := enc.NextEntry(false); err != nil {
			return err
		}
		switch {
		case elem == nil:
			// Write the zero value of the union type.
			if err := vdl.ZeroValue(__VDLType_union_2).VDLWrite(enc); err != nil {
				return err
			}
		default:
			if err := elem.VDLWrite(enc); err != nil {
				return err
			}
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *DataWithSignature) VDLRead(dec vdl.Decoder) error {
	*x = DataWithSignature{}
	if err := dec.StartValue(__VDLType_struct_3); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_3 {
			index = __VDLType_struct_3.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			if err := __VDLReadAnon_list_1(dec, &x.Data); err != nil {
				return err
			}
		case 1:
			if err := dec.ReadValueBytes(-1, &x.BlessingsHash); err != nil {
				return err
			}
		case 2:
			if err := x.AuthorSigned.VDLRead(dec); err != nil {
				return err
			}
		case 3:
			switch value, err := dec.ReadValueBool(); {
			case err != nil:
				return err
			default:
				x.IsValidated = value
			}
		case 4:
			if err := dec.ReadValueBytes(-1, &x.ValidatorDataHash); err != nil {
				return err
			}
		case 5:
			if err := x.ValidatorSigned.VDLRead(dec); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_list_1(dec vdl.Decoder, x *[]Item) error {
	if err := dec.StartValue(__VDLType_list_4); err != nil {
		return err
	}
	if len := dec.LenHint(); len > 0 {
		*x = make([]Item, 0, len)
	} else {
		*x = nil
	}
	for {
		switch done, err := dec.NextEntry(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		default:
			var elem Item
			if err := VDLReadItem(dec, &elem); err != nil {
				return err
			}
			*x = append(*x, elem)
		}
	}
}

// WireValidatorData is the wire form of ValidatorData.
// It excludes the unmarshalled form of the public key.
type WireValidatorData struct {
	Names               []string // Names of valid signing blessings in the Blessings referred to by BlessingsHash.
	MarshalledPublicKey []byte   // PublicKey, marshalled with MarshalBinary().
}

func (WireValidatorData) __VDLReflect(struct {
	Name string `vdl:"v.io/x/ref/services/syncbase/signing.WireValidatorData"`
}) {
}

func (x WireValidatorData) VDLIsZero() bool {
	if len(x.Names) != 0 {
		return false
	}
	if len(x.MarshalledPublicKey) != 0 {
		return false
	}
	return true
}

func (x WireValidatorData) VDLWrite(enc vdl.Encoder) error {
	if err := enc.StartValue(__VDLType_struct_6); err != nil {
		return err
	}
	if len(x.Names) != 0 {
		if err := enc.NextField(0); err != nil {
			return err
		}
		if err := __VDLWriteAnon_list_2(enc, x.Names); err != nil {
			return err
		}
	}
	if len(x.MarshalledPublicKey) != 0 {
		if err := enc.NextFieldValueBytes(1, __VDLType_list_1, x.MarshalledPublicKey); err != nil {
			return err
		}
	}
	if err := enc.NextField(-1); err != nil {
		return err
	}
	return enc.FinishValue()
}

func __VDLWriteAnon_list_2(enc vdl.Encoder, x []string) error {
	if err := enc.StartValue(__VDLType_list_7); err != nil {
		return err
	}
	if err := enc.SetLenHint(len(x)); err != nil {
		return err
	}
	for _, elem := range x {
		if err := enc.NextEntryValueString(vdl.StringType, elem); err != nil {
			return err
		}
	}
	if err := enc.NextEntry(true); err != nil {
		return err
	}
	return enc.FinishValue()
}

func (x *WireValidatorData) VDLRead(dec vdl.Decoder) error {
	*x = WireValidatorData{}
	if err := dec.StartValue(__VDLType_struct_6); err != nil {
		return err
	}
	decType := dec.Type()
	for {
		index, err := dec.NextField()
		switch {
		case err != nil:
			return err
		case index == -1:
			return dec.FinishValue()
		}
		if decType != __VDLType_struct_6 {
			index = __VDLType_struct_6.FieldIndexByName(decType.Field(index).Name)
			if index == -1 {
				if err := dec.SkipValue(); err != nil {
					return err
				}
				continue
			}
		}
		switch index {
		case 0:
			if err := __VDLReadAnon_list_2(dec, &x.Names); err != nil {
				return err
			}
		case 1:
			if err := dec.ReadValueBytes(-1, &x.MarshalledPublicKey); err != nil {
				return err
			}
		}
	}
}

func __VDLReadAnon_list_2(dec vdl.Decoder, x *[]string) error {
	if err := dec.StartValue(__VDLType_list_7); err != nil {
		return err
	}
	if len := dec.LenHint(); len > 0 {
		*x = make([]string, 0, len)
	} else {
		*x = nil
	}
	for {
		switch done, elem, err := dec.NextEntryValueString(); {
		case err != nil:
			return err
		case done:
			return dec.FinishValue()
		default:
			*x = append(*x, elem)
		}
	}
}

// Hold type definitions in package-level variables, for better performance.
var (
	__VDLType_list_1   *vdl.Type
	__VDLType_union_2  *vdl.Type
	__VDLType_struct_3 *vdl.Type
	__VDLType_list_4   *vdl.Type
	__VDLType_struct_5 *vdl.Type
	__VDLType_struct_6 *vdl.Type
	__VDLType_list_7   *vdl.Type
)

var __VDLInitCalled bool

// __VDLInit performs vdl initialization.  It is safe to call multiple times.
// If you have an init ordering issue, just insert the following line verbatim
// into your source files in this package, right after the "package foo" clause:
//
//    var _ = __VDLInit()
//
// The purpose of this function is to ensure that vdl initialization occurs in
// the right order, and very early in the init sequence.  In particular, vdl
// registration and package variable initialization needs to occur before
// functions like vdl.TypeOf will work properly.
//
// This function returns a dummy value, so that it can be used to initialize the
// first var in the file, to take advantage of Go's defined init order.
func __VDLInit() struct{} {
	if __VDLInitCalled {
		return struct{}{}
	}
	__VDLInitCalled = true

	// Register types.
	vdl.Register((*Item)(nil))
	vdl.Register((*DataWithSignature)(nil))
	vdl.Register((*WireValidatorData)(nil))

	// Initialize type definitions.
	__VDLType_list_1 = vdl.TypeOf((*[]byte)(nil))
	__VDLType_union_2 = vdl.TypeOf((*Item)(nil))
	__VDLType_struct_3 = vdl.TypeOf((*DataWithSignature)(nil)).Elem()
	__VDLType_list_4 = vdl.TypeOf((*[]Item)(nil))
	__VDLType_struct_5 = vdl.TypeOf((*security.Signature)(nil)).Elem()
	__VDLType_struct_6 = vdl.TypeOf((*WireValidatorData)(nil)).Elem()
	__VDLType_list_7 = vdl.TypeOf((*[]string)(nil))

	return struct{}{}
}
