swift/jni/ref: Use opts struct for init; use C99 bool

This CL replaces v23_syncbase_Bool with C99's Bool and equivalent
helpers. It also replaces the v23_syncbase_Init parameters with an
options struct, adding a verbose level option that routes to VLog,
and alphabetizes the C struct types and helper functions.

MultiPart: 1/2
Change-Id: I0017b75b12a0a611c131561ab2c753953b205e1c
diff --git a/services/syncbase/bridge/cgo/impl.go b/services/syncbase/bridge/cgo/impl.go
index ce14e19..3eda95f 100644
--- a/services/syncbase/bridge/cgo/impl.go
+++ b/services/syncbase/bridge/cgo/impl.go
@@ -44,6 +44,7 @@
 	"v.io/v23/syncbase/util"
 	"v.io/v23/verror"
 	"v.io/v23/vom"
+	"v.io/x/lib/vlog"
 	_ "v.io/x/ref/runtime/factories/roaming"
 	"v.io/x/ref/services/syncbase/bridge"
 	"v.io/x/ref/services/syncbase/bridge/cgo/ptrmap"
@@ -98,32 +99,20 @@
 
 var globalPtrMap = ptrmap.New()
 
-// TODO(razvanm): Replace the function arguments with an options struct.
-//export v23_syncbase_Init
-func v23_syncbase_Init(cClientUnderstandVom C.v23_syncbase_Bool, cRootDir C.v23_syncbase_String, cTestLogin C.v23_syncbase_Bool) {
-	if b != nil {
-		panic("v23_syncbase_Init called again before a v23_syncbase_Shutdown")
+type (
+	initOpts struct {
+		clientUnderstandsVOM bool
+		rootDir              string
+		testLogin            bool
+		verboseLevel         int
 	}
-	// Strip all flags beyond the binary name; otherwise, v23.Init will fail when it encounters
-	// unknown flags passed by Xcode, e.g. NSTreatUnknownArgumentsAsOpen.
-	os.Args = os.Args[:1]
-	ctx, shutdown := v23.Init()
-	b = &bridge.Bridge{Ctx: ctx, Shutdown: shutdown}
-	rootDir = cRootDir.extract()
-	clientUnderstandsVOM = cClientUnderstandVom.extract()
-	testLogin = cTestLogin.extract()
-	var cErr C.v23_syncbase_VError
-	if isLoggedIn() {
-		v23_syncbase_Serve(&cErr)
-	}
-	neighborhoodAdStatus = newAdStatus()
-}
 
-type adStatus struct {
-	isAdvertising bool
-	cancel        context.CancelFunc
-	done          <-chan struct{}
-}
+	adStatus struct {
+		isAdvertising bool
+		cancel        context.CancelFunc
+		done          <-chan struct{}
+	}
+)
 
 func newAdStatus() *adStatus {
 	return &adStatus{}
@@ -143,6 +132,34 @@
 		a.cancel = nil
 		a.done = nil
 	}
+
+}
+
+//export v23_syncbase_Init
+func v23_syncbase_Init(cOpts C.v23_syncbase_InitOpts) {
+	if b != nil {
+		panic("v23_syncbase_Init called again before a v23_syncbase_Shutdown")
+	}
+	opts := cOpts.extract()
+
+	// Strip all flags beyond the binary name; otherwise, v23.Init will fail when it encounters
+	// unknown flags passed by Xcode, e.g. NSTreatUnknownArgumentsAsOpen.
+	os.Args = os.Args[:1]
+	ctx, shutdown := v23.Init()
+	if opts.verboseLevel > 0 {
+		vlog.Log.Configure(vlog.OverridePriorConfiguration(true), vlog.Level(opts.verboseLevel))
+		vlog.Info("Verbose logging turned on")
+	}
+	b = &bridge.Bridge{Ctx: ctx, Shutdown: shutdown}
+	rootDir = opts.rootDir
+	clientUnderstandsVOM = opts.clientUnderstandsVOM
+	testLogin = opts.testLogin
+	if isLoggedIn() {
+		// This cErr will always be nil since we just checked isLoggedIn.
+		var cErr C.v23_syncbase_VError
+		v23_syncbase_Serve(&cErr)
+	}
+	neighborhoodAdStatus = newAdStatus()
 }
 
 //export v23_syncbase_Serve
@@ -185,7 +202,7 @@
 }
 
 //export v23_syncbase_IsLoggedIn
-func v23_syncbase_IsLoggedIn(cIsLoggedIn *C.v23_syncbase_Bool) {
+func v23_syncbase_IsLoggedIn(cIsLoggedIn *C.bool) {
 	cIsLoggedIn.init(isLoggedIn())
 }
 
@@ -337,7 +354,7 @@
 }
 
 //export v23_syncbase_NeighborhoodIsAdvertising
-func v23_syncbase_NeighborhoodIsAdvertising(cBool *C.v23_syncbase_Bool) {
+func v23_syncbase_NeighborhoodIsAdvertising(cBool *C.bool) {
 	cBool.init(neighborhoodAdStatus.isAdvertising)
 }
 
@@ -407,7 +424,7 @@
 }
 
 //export v23_syncbase_DbExists
-func v23_syncbase_DbExists(cName C.v23_syncbase_String, cExists *C.v23_syncbase_Bool, cErr *C.v23_syncbase_VError) {
+func v23_syncbase_DbExists(cName C.v23_syncbase_String, cExists *C.bool, cErr *C.v23_syncbase_VError) {
 	name := cName.extract()
 	ctx, call := b.NewCtxCall(name, bridge.MethodDesc(wire.DatabaseDesc, "Exists"))
 	stub, err := b.GetDb(ctx, call, name)
@@ -819,7 +836,7 @@
 }
 
 //export v23_syncbase_CollectionExists
-func v23_syncbase_CollectionExists(cName, cBatchHandle C.v23_syncbase_String, cExists *C.v23_syncbase_Bool, cErr *C.v23_syncbase_VError) {
+func v23_syncbase_CollectionExists(cName, cBatchHandle C.v23_syncbase_String, cExists *C.bool, cErr *C.v23_syncbase_VError) {
 	name := cName.extract()
 	batchHandle := wire.BatchHandle(cBatchHandle.extract())
 	ctx, call := b.NewCtxCall(name, bridge.MethodDesc(wire.CollectionDesc, "Exists"))
@@ -952,7 +969,7 @@
 // Row
 
 //export v23_syncbase_RowExists
-func v23_syncbase_RowExists(cName, cBatchHandle C.v23_syncbase_String, cExists *C.v23_syncbase_Bool, cErr *C.v23_syncbase_VError) {
+func v23_syncbase_RowExists(cName, cBatchHandle C.v23_syncbase_String, cExists *C.bool, cErr *C.v23_syncbase_VError) {
 	name := cName.extract()
 	batchHandle := wire.BatchHandle(cBatchHandle.extract())
 	ctx, call := b.NewCtxCall(name, bridge.MethodDesc(wire.RowDesc, "Exists"))
diff --git a/services/syncbase/bridge/cgo/jni.go b/services/syncbase/bridge/cgo/jni.go
index 9f3baec..c60ffc2 100644
--- a/services/syncbase/bridge/cgo/jni.go
+++ b/services/syncbase/bridge/cgo/jni.go
@@ -123,7 +123,12 @@
 //export Java_io_v_syncbase_internal_Service_Init
 func Java_io_v_syncbase_internal_Service_Init(env *C.JNIEnv, cls C.jclass, initRoot C.jstring, testLogin C.jboolean) {
 	cInitRoot := newVStringFromJava(env, initRoot)
-	v23_syncbase_Init(C.v23_syncbase_Bool(1), cInitRoot, C.v23_syncbase_Bool(testLogin))
+	v23_syncbase_Init(initOpts{
+		clientUnderstandsVOM: true,
+		rootDir:              cInitRoot.extract(),
+		testLogin:            bool(testLogin),
+		verboseLevel:         0,
+	})
 }
 
 //export Java_io_v_syncbase_internal_Service_Serve
diff --git a/services/syncbase/bridge/cgo/lib.h b/services/syncbase/bridge/cgo/lib.h
index 505d180..d03b864 100644
--- a/services/syncbase/bridge/cgo/lib.h
+++ b/services/syncbase/bridge/cgo/lib.h
@@ -11,8 +11,6 @@
 ////////////////////////////////////////
 // Generic types
 
-typedef uint8_t v23_syncbase_Bool;
-
 // string
 typedef struct {
   char* p;
@@ -51,17 +49,13 @@
 ////////////////////////////////////////
 // Syncbase-specific types
 
-// syncbase.Id
-typedef struct {
-  v23_syncbase_String blessing;
-  v23_syncbase_String name;
-} v23_syncbase_Id;
 
-// []syncbase.Id
+// syncbase.discovery.AppPeer
 typedef struct {
-  v23_syncbase_Id* p;
-  int n;
-} v23_syncbase_Ids;
+  v23_syncbase_String appName;
+  v23_syncbase_String blessings;
+  bool isLost;
+} v23_syncbase_AppPeer;
 
 // syncbase.BatchOptions
 typedef struct {
@@ -95,17 +89,32 @@
   v23_syncbase_EntityTypeRow = 2
 } v23_syncbase_EntityType;
 
-// syncbase.WatchChange
+// syncbase.Id
 typedef struct {
-  v23_syncbase_EntityType entityType;
-  v23_syncbase_Id collection;
-  v23_syncbase_String row;
-  v23_syncbase_ChangeType changeType;
-  v23_syncbase_Bytes value;
-  v23_syncbase_Bytes resumeMarker;
-  bool fromSync;
-  bool continued;
-} v23_syncbase_WatchChange;
+  v23_syncbase_String blessing;
+  v23_syncbase_String name;
+} v23_syncbase_Id;
+
+// []syncbase.Id
+typedef struct {
+  v23_syncbase_Id* p;
+  int n;
+} v23_syncbase_Ids;
+
+// cgo.InitOpts
+typedef struct {
+    bool clientUnderstandsVOM;
+    v23_syncbase_String rootDir;
+    bool testLogin;
+    int verboseLevel;
+} v23_syncbase_InitOpts;
+
+// syncbase.discovery.Invite
+typedef struct {
+  v23_syncbase_Id syncgroup;
+  v23_syncbase_Strings addresses;
+  v23_syncbase_Strings blessingNames;
+} v23_syncbase_Invite;
 
 // syncbase.KeyValue
 typedef struct {
@@ -136,19 +145,17 @@
   int n;
 } v23_syncbase_SyncgroupMemberInfoMap;
 
-// syncbase.discovery.Invite
+// syncbase.WatchChange
 typedef struct {
-  v23_syncbase_Id syncgroup;
-  v23_syncbase_Strings addresses;
-  v23_syncbase_Strings blessingNames;
-} v23_syncbase_Invite;
-
-// syncbase.discovery.AppPeer
-typedef struct {
-  v23_syncbase_String appName;
-  v23_syncbase_String blessings;
-  bool isLost;
-} v23_syncbase_AppPeer;
+  v23_syncbase_EntityType entityType;
+  v23_syncbase_Id collection;
+  v23_syncbase_String row;
+  v23_syncbase_ChangeType changeType;
+  v23_syncbase_Bytes value;
+  v23_syncbase_Bytes resumeMarker;
+  bool fromSync;
+  bool continued;
+} v23_syncbase_WatchChange;
 
 ////////////////////////////////////////
 // Functions
diff --git a/services/syncbase/bridge/cgo/types.go b/services/syncbase/bridge/cgo/types.go
index 902bbd8..3ca05a1 100644
--- a/services/syncbase/bridge/cgo/types.go
+++ b/services/syncbase/bridge/cgo/types.go
@@ -28,6 +28,26 @@
 import "C"
 
 ////////////////////////////////////////////////////////////
+// C.bool
+
+func (x *C.bool) init(b bool) {
+	*x = C.bool(b)
+}
+
+func (x *C.bool) extract() bool {
+	return bool(*x)
+}
+
+////////////////////////////////////////////////////////////
+// C.v23_syncbase_AppPeer
+
+func (x *C.v23_syncbase_AppPeer) init(peer discovery.AppPeer) {
+	x.appName.init(peer.AppName)
+	x.blessings.init(peer.Blessings)
+	x.isLost = C.bool(peer.Lost)
+}
+
+////////////////////////////////////////////////////////////
 // C.v23_syncbase_BatchOptions
 
 func (x *C.v23_syncbase_BatchOptions) init(opts wire.BatchOptions) {
@@ -43,24 +63,6 @@
 }
 
 ////////////////////////////////////////////////////////////
-// C.v23_syncbase_Bool
-
-func (x *C.v23_syncbase_Bool) init(b bool) {
-	if b == false {
-		*x = 0
-	} else {
-		*x = 1
-	}
-}
-
-func (x *C.v23_syncbase_Bool) extract() bool {
-	if *x == 0 {
-		return false
-	}
-	return true
-}
-
-////////////////////////////////////////////////////////////
 // C.v23_syncbase_Bytes
 
 func init() {
@@ -208,6 +210,35 @@
 }
 
 ////////////////////////////////////////////////////////////
+// C.v23_syncbase_Invite
+
+func (x *C.v23_syncbase_Invite) init(invite discovery.Invite) {
+	x.syncgroup.init(invite.Syncgroup)
+	x.addresses.init(invite.Addresses)
+	x.blessingNames.init(invite.BlessingNames)
+}
+
+////////////////////////////////////////////////////////////
+// C.v23_syncbase_InitOpts
+
+func (x *C.v23_syncbase_InitOpts) init(opts initOpts) {
+	x.clientUnderstandsVOM.init(opts.clientUnderstandsVOM)
+	x.rootDir.init(opts.rootDir)
+	x.testLogin.init(opts.testLogin)
+	(*x).verboseLevel = C.int(opts.verboseLevel)
+}
+
+func (x *C.v23_syncbase_InitOpts) extract() initOpts {
+	return initOpts{
+		clientUnderstandsVOM: bool(x.clientUnderstandsVOM),
+		rootDir:              x.rootDir.extract(),
+		testLogin:            bool(x.testLogin),
+		verboseLevel:         int(x.verboseLevel),
+	}
+
+}
+
+////////////////////////////////////////////////////////////
 // C.v23_syncbase_KeyValue
 
 func (x *C.v23_syncbase_KeyValue) init(key string, value []byte) {
@@ -445,21 +476,3 @@
 	x.continued = C.bool(wc.Continued)
 	return nil
 }
-
-////////////////////////////////////////////////////////////
-// C.v23_syncbase_Invite
-
-func (x *C.v23_syncbase_Invite) init(invite discovery.Invite) {
-	x.syncgroup.init(invite.Syncgroup)
-	x.addresses.init(invite.Addresses)
-	x.blessingNames.init(invite.BlessingNames)
-}
-
-////////////////////////////////////////////////////////////
-// C.v23_syncbase_AppPeer
-
-func (x *C.v23_syncbase_AppPeer) init(peer discovery.AppPeer) {
-	x.appName.init(peer.AppName)
-	x.blessings.init(peer.Blessings)
-	x.isLost = C.bool(peer.Lost)
-}