CHOICE

The ASN.1 CHOICE type is converted into a Go struct containing an integer for the choice tag value (T) followed by a struct (U) with a field for each of the CHOICE elements. This differs from C/C++, where a union type is used for the set of alternatives. There is no union type in Go, so a struct containing pointer values for all of the alternatives is used. The T field indicates which of the alternatives is chosen and which of the fields in the U struct shall be non-nil; exactly one field shall be non-nil at a time.

The tag value is simply a sequential number starting at one for each alternative in the CHOICE. A Go constant is generated for each of these values. The format of this constant is <name><element-name>TAG where <name> is the name of the ASN.1 production and <element-name> is the name of the CHOICE alternative.

The fields of the U struct, corresponding to the alternatives for the CHOICE type, are generated much the same as for the elements of a SEQUENCE type (described earlier), except that pointer types are used. The compiler internally pulls out any nested constructed types and creates an ASN.1 type for it, and that is reflected in the generated code.

ASN.1 production:

   <name> ::= CHOICE {
      <element1-name> <element1-type>,
      <element2-name> <element2-type>,
      ...
   }

Generated Go code:

    const (
        <name>_<element1-name>TAG = 1
        <name>_<element2-name>TAG = 2
        ...
    )

    type <name> struct {
        T uint64
        U struct {
            <type1> *<element1-name>
            <type2> *<element2-name>
            ...
        }
    }