github.com/glycerine/zebrapack@v4.1.1-0.20181107023619-e955d028f9bf+incompatible/zebra/zebra.go (about)

     1  /*
     2  package zebra specifies the ZebraPack serialization format.
     3  Instead of an IDL file, the ZebraPack schema is described
     4  using the same Go source file that holds the Go structs
     5  you wish to serialize. The Go file schema is then compiled
     6  by running `zebrapack` into msgpack2 (with optional JSON)
     7  in a format we'll call `compiled-schema` format. If
     8  one is not starting in Go, simply write a standalone Go
     9  file that describes your types. See the examples
    10  in `../testdata/my.go`.
    11  
    12  The `compiled-schema` is thus type checked upon generation,
    13  and other languages need not parse Go (only msgpack2
    14  or JSON) in order the read and use the compiled
    15  schema to undertand the types on the wire. The
    16  types below desribe those found in
    17  the compiled ZebraPack schema files.
    18  
    19  The methods that you see below in the godoc are
    20  the autogenerated methods from running
    21  `zebrapack -msg -file zebra.go` on this file itself.
    22  They provide an API for reading and writing
    23  compiled ZebraPack schema.
    24  */
    25  package zebra
    26  
    27  // in the generate command, we use -msgp so that
    28  // we serialize the ZebraPack schema itself
    29  // as simple msgpack2, rather than in ZebraPack format.
    30  
    31  //go:generate zebrapack -msgp
    32  
    33  const zebraSchemaId64 = 0x1a5a94bd49624
    34  
    35  // Zkind describes the detailed type of the field.
    36  // Since it also stores the fixed size of a array type,
    37  // it needs to be large. When serialized as msgpack2,
    38  // it will be compressed.
    39  //
    40  // Implentation note: primitives must correspond
    41  // to gen/Primitive, as we will cast/convert them directly.
    42  //
    43  type Zkind uint64
    44  
    45  const (
    46  
    47  	// primitives.
    48  	// Implementation note: must correspond to gen/Primitive.
    49  	Invalid    Zkind = 0
    50  	Bytes      Zkind = 1 // []byte
    51  	String     Zkind = 2
    52  	Float32    Zkind = 3
    53  	Float64    Zkind = 4
    54  	Complex64  Zkind = 5
    55  	Complex128 Zkind = 6
    56  	Uint       Zkind = 7 // 32 or 64 bit; as in Go, matches native word
    57  	Uint8      Zkind = 8
    58  	Uint16     Zkind = 9
    59  	Uint32     Zkind = 10
    60  	Uint64     Zkind = 11
    61  	Byte       Zkind = 12
    62  	Int        Zkind = 13 // as in Go, matches native word size.
    63  	Int8       Zkind = 14
    64  	Int16      Zkind = 15
    65  	Int32      Zkind = 16
    66  	Int64      Zkind = 17
    67  	Bool       Zkind = 18
    68  	Intf       Zkind = 19 // interface{}, the empty interface.
    69  	Time       Zkind = 20 // time.Time
    70  	Ext        Zkind = 21 // extension
    71  
    72  	// IDENT means an unrecognized identifier;
    73  	// it typically means a named struct type.
    74  	// The Str field in the Ztype will hold the
    75  	// name of the struct.
    76  	IDENT Zkind = 22
    77  
    78  	// compound types
    79  	// implementation note: should correspond to gen/Elem.
    80  	BaseElemCat Zkind = 23
    81  	MapCat      Zkind = 24
    82  	StructCat   Zkind = 25
    83  	SliceCat    Zkind = 26
    84  	ArrayCat    Zkind = 27
    85  	PointerCat  Zkind = 28
    86  
    87  	IDENTiface Zkind = 29 // an identifier that is an inteface (known b/c of struct tag 'iface')
    88  )
    89  
    90  // Ztype describes any type, be it a BaseElem,
    91  // Map, Struct, Slice, Array, or Pointer.
    92  type Ztype struct {
    93  
    94  	// Kind gives the exact type for primitives,
    95  	// and the category for compound types.
    96  	Kind Zkind `zid:"0"`
    97  
    98  	// Str holds the struct name when Kind == 22 (IDENT) or 29 (IDENTiface).
    99  	// Otherwise it typically reflects Kind directly
   100  	// which is useful for human readability.
   101  	Str string `msg:",omitempty" zid:"1"`
   102  
   103  	// Domain holds the key type for maps. For
   104  	// pointers and slices it holds the element type.
   105  	// For arrays, it holds the fixed size.
   106  	// Domain is null when Kind is a primitive.
   107  	Domain *Ztype `msg:",omitempty" zid:"2"`
   108  
   109  	// Range holds the value type for maps.
   110  	// For arrays (always a fixed size), Range holds
   111  	// the element type.  Otherwise Range is
   112  	// typically null.
   113  	Range *Ztype `msg:",omitempty" zid:"3"`
   114  }
   115  
   116  // Schema is the top level container in ZebraPack.
   117  // It all starts here.
   118  type Schema struct {
   119  
   120  	// SourcePath gives the path to the original Go
   121  	// source file that was parsed to produce this
   122  	// compiled schema.
   123  	SourcePath string `msg:",omitempty" zid:"0"`
   124  
   125  	// SourcePackage notes the original package presented
   126  	// by the SourcePath file.
   127  	SourcePackage string `msg:",omitempty" zid:"1"`
   128  
   129  	// ZebraSchemaId is a randomly chosen but stable
   130  	// 53-bit positive integer identifier (see
   131  	// zebrapack -genid) that can be used to distinguish schemas.
   132  	ZebraSchemaId int64 `msg:",omitempty" zid:"2"`
   133  
   134  	// Structs holds the collection of the main data
   135  	// descriptor, the Struct. The key is identical
   136  	// to Struct.StructName.
   137  	//
   138  	// This a map rather than a slice in order to:
   139  	// a) insure there are no duplicate struct names; and
   140  	// b) make decoding easy and fast.
   141  	Structs map[string]*Struct `msg:",omitempty" zid:"3"`
   142  
   143  	// Imports archives the imports in the SourcePath
   144  	// to make it possible to understand other package
   145  	// type references.
   146  	Imports []string `msg:",omitempty" zid:"4"`
   147  }
   148  
   149  // Struct represents a single message or struct.
   150  type Struct struct {
   151  	// StructName is the typename of the struct in Go.
   152  	StructName string `msg:",omitempty" zid:"0"`
   153  
   154  	// Fields hold the individual Field descriptors.
   155  	Fields []Field `msg:",omitempty" zid:"1"`
   156  }
   157  
   158  // Field represents fields within a struct.
   159  type Field struct {
   160  
   161  	// Zid is the zebrapack id.
   162  	//
   163  	// Zid numbering detects update collisions
   164  	// when two developers simultaneously add two
   165  	// new fields. Zid numbering allows sane
   166  	// forward/backward data evolution, like protobufs
   167  	// and Cap'nProto.
   168  	//
   169  	// Zid follows Cap'nProto numbering semantics:
   170  	// start at numbering at 0, and strictly/always
   171  	// increase numbers monotically.
   172  	//
   173  	// No gaps and no duplicate Zid are allowed.
   174  	//
   175  	// Duplicate numbers are how collisions (between two
   176  	// developers adding two distinct new fields independently
   177  	// but at the same time) are detected.
   178  	//
   179  	// Therefore this ironclad rule: never delete a field or Zid number,
   180  	// just mark it as deprecated with the `deprecated:"true"`
   181  	// tag. Change its Go type to struct{} as soon as
   182  	// possible so that it becomes skipped; then the Go
   183  	// compiler can help you detect and prevent unwanted use.
   184  	//
   185  	Zid int64 `zid:"0"`
   186  
   187  	// the name of the field in the Go schema/source file.
   188  	FieldGoName string `zid:"1"`
   189  
   190  	// optional wire-name designated by a
   191  	// `msg:"tagname"` tag on the struct field.
   192  	FieldTagName string `msg:",omitempty" zid:"2"`
   193  
   194  	// =======================
   195  	// type info
   196  	// =======================
   197  
   198  	// human readable/Go type description
   199  	FieldTypeStr string `msg:",omitempty" zid:"3"`
   200  
   201  	// the broad category of this type. empty if Skip is true
   202  	FieldCategory Zkind `msg:",omitempty" zid:"4"`
   203  
   204  	// avail if FieldCategory == BaseElemCat
   205  	FieldPrimitive Zkind `msg:",omitempty" zid:"5"`
   206  
   207  	// the machine-parse-able type tree
   208  	FieldFullType *Ztype `msg:",omitempty" zid:"6"`
   209  
   210  	// =======================
   211  	// field tag details:
   212  	// =======================
   213  
   214  	// if OmitEmpty then we don't serialize
   215  	// the field if it has its zero-value.
   216  	OmitEmpty bool `msg:",omitempty" zid:"7"`
   217  
   218  	// Skip means either type struct{} or
   219  	// other unserializable type;
   220  	// or marked  as `msg:"-"`. In any case,
   221  	// if Skip is true: do not serialize
   222  	// this field when writing, and ignore it
   223  	// when reading.
   224  	Skip bool `msg:",omitempty" zid:"8"`
   225  
   226  	// Deprecated means tagged with `deprecated:"true"`,
   227  	// or `msg:",deprecated"`.
   228  	// Compilers/libraries should discourage and warn
   229  	// users away from writing to such fields, while
   230  	// not making it impossible to either read or write
   231  	// the field.
   232  	Deprecated bool `msg:",omitempty" zid:"9"`
   233  
   234  	// ShowZero means display the field even if
   235  	// it has the zero value. Showzero has no impact
   236  	// on what is transmitted on the wire. Zero
   237  	// valued fields are never transmitted.
   238  	ShowZero bool `msg:",omitempty" zid:"10"`
   239  }