blob: ba1249157648f23dd5c174f4424486245168ac47 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package types
import "fmt"
// TODO(FIDL-524): Remove post migration.
type methodOrdinal uint64
func (wrapper methodOrdinal) String() string {
return fmt.Sprintf("%#x", uint64(wrapper))
}
// NamedOrdinal represents a named ordinal.
type NamedOrdinal struct {
Name string
Ordinal methodOrdinal
}
// Ordinals represents the two ordinals ord and gen as they move through
// their migration. It exposes convenience methods to have generic code
// generation, and control the status of the migration in one central place.
//
// Read more about migration strategy on FIDL-524.
type Ordinals struct {
ord NamedOrdinal
gen NamedOrdinal
writeGen bool
}
// NewOrdinalsStep3 creates an Ordinals using the `ordName`, and `genName`
// provided.
//
// Step #3 of migration: ord << 32, gen is not shifted (read from fidlc
// directly)
func NewOrdinalsStep3(method Method, ordName, genName string) Ordinals {
return Ordinals{
ord: NamedOrdinal{
Name: ordName,
Ordinal: methodOrdinal(method.Ordinal << 32),
},
gen: NamedOrdinal{
Name: genName,
Ordinal: methodOrdinal(method.GenOrdinal),
},
writeGen: true,
}
}
// NewOrdinalsStep5 creates an Ordinals using the `ordName`, and `genName`
// provided.
//
// Step #5 of migration: neither ord nor gen are shifted (they are read directly
// from fidlc)
func NewOrdinalsStep5(method Method, ordName, genName string) Ordinals {
return Ordinals{
ord: NamedOrdinal{
Name: ordName,
Ordinal: methodOrdinal(method.Ordinal),
},
gen: NamedOrdinal{
Name: genName,
Ordinal: methodOrdinal(method.GenOrdinal),
},
}
}
// NewOrdinalsStep7 creates an Ordinals using the `ordName`, and `genName`
// provided.
//
// Step #7 of migration: neither ord nor gen are shifted (they are read directly
// from fidlc). Send gen, which is 64b version.
func NewOrdinalsStep7(method Method, ordName, genName string) Ordinals {
return Ordinals{
ord: NamedOrdinal{
Name: ordName,
Ordinal: methodOrdinal(method.Ordinal),
},
gen: NamedOrdinal{
Name: genName,
Ordinal: methodOrdinal(method.GenOrdinal),
},
writeGen: true,
}
}
// Reads returns all distinct ordinals to be used on read, i.e. either
// ord, gen, or both, depending on the current status of the migration.
func (ords Ordinals) Reads() []NamedOrdinal {
var (
reads []NamedOrdinal
includeOrd = ords.ord.Ordinal != 0
includeGen = ords.gen.Ordinal != 0
)
if includeOrd && includeGen && ords.ord.Ordinal == ords.gen.Ordinal {
if ords.writeGen {
reads = append(reads, ords.gen)
} else {
reads = append(reads, ords.ord)
}
} else {
if includeOrd {
reads = append(reads, ords.ord)
}
if includeGen {
reads = append(reads, ords.gen)
}
}
if len(reads) == 0 {
panic(fmt.Sprintf("illegal migration step, no read ordinal: %v", ords))
}
return reads
}
// Write returns the ordinal to be used on write, i.e. either ord or gen,
// depending on the current status of the migration.
func (ords Ordinals) Write() NamedOrdinal {
if ords.writeGen {
return ords.gen
} else {
return ords.ord
}
}