var DefaultContainer … var noAliases … // NewContainer creates a new Container with the fully-qualified name. func NewContainer(opts ...ContainerOption) (*Container, error) { … } type Container … // Extend creates a new Container with the existing settings and applies a series of // ContainerOptions to further configure the new container. func (c *Container) Extend(opts ...ContainerOption) (*Container, error) { … } // Name returns the fully-qualified name of the container. // // The name may conceptually be a namespace, package, or type. func (c *Container) Name() string { … } // ResolveCandidateNames returns the candidates name of namespaced identifiers in C++ resolution // order. // // Names which shadow other names are returned first. If a name includes a leading dot ('.'), // the name is treated as an absolute identifier which cannot be shadowed. // // Given a container name a.b.c.M.N and a type name R.s, this will deliver in order: // // a.b.c.M.N.R.s // a.b.c.M.R.s // a.b.c.R.s // a.b.R.s // a.R.s // R.s // // If aliases or abbreviations are configured for the container, then alias names will take // precedence over containerized names. func (c *Container) ResolveCandidateNames(name string) []string { … } // aliasSet returns the alias to fully-qualified name mapping stored in the container. func (c *Container) aliasSet() map[string]string { … } // findAlias takes a name as input and returns an alias expansion if one exists. // // If the name is qualified, the first component of the qualified name is checked against known // aliases. Any alias that is found in a qualified name is expanded in the result: // // alias: R -> my.alias.R // name: R.S.T // output: my.alias.R.S.T // // Note, the name must not have a leading dot. func (c *Container) findAlias(name string) (string, bool) { … } type ContainerOption … // Abbrevs configures a set of simple names as abbreviations for fully-qualified names. // // An abbreviation (abbrev for short) is a simple name that expands to a fully-qualified name. // Abbreviations can be useful when working with variables, functions, and especially types from // multiple namespaces: // // // CEL object construction // qual.pkg.version.ObjTypeName{ // field: alt.container.ver.FieldTypeName{value: ...} // } // // Only one the qualified names above may be used as the CEL container, so at least one of these // references must be a long qualified name within an otherwise short CEL program. Using the // following abbreviations, the program becomes much simpler: // // // CEL Go option // Abbrevs("qual.pkg.version.ObjTypeName", "alt.container.ver.FieldTypeName") // // Simplified Object construction // ObjTypeName{field: FieldTypeName{value: ...}} // // There are a few rules for the qualified names and the simple abbreviations generated from them: // - Qualified names must be dot-delimited, e.g. `package.subpkg.name`. // - The last element in the qualified name is the abbreviation. // - Abbreviations must not collide with each other. // - The abbreviation must not collide with unqualified names in use. // // Abbreviations are distinct from container-based references in the following important ways: // - Abbreviations must expand to a fully-qualified name. // - Expanded abbreviations do not participate in namespace resolution. // - Abbreviation expansion is done instead of the container search for a matching identifier. // - Containers follow C++ namespace resolution rules with searches from the most qualified name // to the least qualified name. // - Container references within the CEL program may be relative, and are resolved to fully // qualified names at either type-check time or program plan time, whichever comes first. // // If there is ever a case where an identifier could be in both the container and as an // abbreviation, the abbreviation wins as this will ensure that the meaning of a program is // preserved between compilations even as the container evolves. func Abbrevs(qualifiedNames ...string) ContainerOption { … } // Alias associates a fully-qualified name with a user-defined alias. // // In general, Abbrevs is preferred to Alias since the names generated from the Abbrevs option // are more easily traced back to source code. The Alias option is useful for propagating alias // configuration from one Container instance to another, and may also be useful for remapping // poorly chosen protobuf message / package names. // // Note: all of the rules that apply to Abbrevs also apply to Alias. func Alias(qualifiedName, alias string) ContainerOption { … } func aliasAs(kind, qualifiedName, alias string) ContainerOption { … } // Name sets the fully-qualified name of the Container. func Name(name string) ContainerOption { … } // ToQualifiedName converts an expression AST into a qualified name if possible, with a boolean // 'found' value that indicates if the conversion is successful. func ToQualifiedName(e ast.Expr) (string, bool) { … }