ref: Change vdl go codegen to emit __VDLInit funcs.

Fixes a subtle init-ordering issue in vdl-generated go code.  The
basic problem looks something like this; there are many variants
to this problem, this is just one simple example:

// User's file a.go
package foo
import "v.io/v23/vdl"
var myType := vdl.TypeOf(FooType{})

// Generated file foo.vdl.go
package foo
import "v.io/v23/vdl"
func init() {
vdl.RegisterNative(FooToNative, FooFromNative)
}

The problem is that the vdl.RegisterNative call must occur before
the vdl.TypeOf call, so that the vdl package knows about native
types, and can analyze the type correctly.  But init funcs are
always processed after all package-level variables have been
initialized, so we get the wrong order above.

We fix that by moving all initialization into a generated
__VDLInit func, with a trick to turn it into a var
initialization.  Note that we still haven't fixed the above
example, since the package-level vars in a.go are typically
processed before foo.vdl.go.  In the rare case where this
happens, the user can add a call to __VDLInit in a var
initializer early in their a.go file.

Similar problems existed with vom.RawBytesOf, and the
manually-generated types we were storing in package-level vars.

The new strategy is to put all ordering-dependent init logic in
__VDLInit, and to ensure that the order that we call things
within the function is correct.  We also sort types, consts and
interfaces in the compiler as best we can.  Note that sorting
types isn't strictly required (or meaningful), since we allow
cyclic types.  But it still might be nice for some generated
languages.

There are further cleanups possible; we can probably add
error-checking more methodically for cases like above where the
user needs to add a call to __VDLInit, and we should replace the
long hex hash for generated type names to a simple counter.  But
that'll occur in a separate CL; this is the more important one.

MultiPart: 3/6

Change-Id: I669e7cfeb3ddf32c4019dcd228550e736bb9f744
diff --git a/services/device/device.vdl.go b/services/device/device.vdl.go
index 4ace3b0..2c3f2a7 100644
--- a/services/device/device.vdl.go
+++ b/services/device/device.vdl.go
@@ -13,8 +13,10 @@
 	"v.io/v23/rpc"
 )
 
-func __VDLEnsureNativeBuilt() {
-}
+var _ = __VDLInit() // Must be first; see __VDLInit comments for details.
+
+//////////////////////////////////////////////////
+// Interface definitions
 
 // ConfigClientMethods is the client interface
 // containing Config methods.
@@ -120,3 +122,26 @@
 		},
 	},
 }
+
+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{}{}
+	}
+
+	return struct{}{}
+}