github.com/chrislusf/greenpack@v3.7.1-0.20170911073826-ad5bd10b7c47+incompatible/green/green.go (about)

     1  /*
     2  package green specifies the Greenpack serialization format.
     3  Instead of an IDL file, the Greenpack 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 `greenpack` 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 Greenpack schema files.
    18  
    19  The methods that you see below in the godoc are
    20  the autogenerated methods from running
    21  `greenpack -file green.go` on this file itself.
    22  They provide an API for reading and writing
    23  compiled Greenpack schema.
    24  */
    25  package green
    26  
    27  // in the generate command, we use -msgp so that
    28  // we serialize the Greenpack schema itself
    29  // as simple msgpack2, rather than in Greenpack format.
    30  
    31  //go:generate greenpack
    32  
    33  const greenSchemaId64 = 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{}
    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  
    88  // Ztype describes any type, be it a BaseElem,
    89  // Map, Struct, Slice, Array, or Pointer.
    90  type Ztype struct {
    91  
    92  	// Kind gives the exact type for primitives,
    93  	// and the category for compound types.
    94  	Kind Zkind
    95  
    96  	// Str holds the struct name when Kind == 22 (IDENT).
    97  	// Otherwise it typically reflects Kind directly
    98  	// which is useful for human readability.
    99  	Str string `msg:",omitempty"`
   100  
   101  	// Domain holds the key type for maps. For
   102  	// pointers and slices it holds the element type.
   103  	// For arrays, it holds the fixed size.
   104  	// Domain is null when Kind is a primitive.
   105  	Domain *Ztype `msg:",omitempty"`
   106  
   107  	// Range holds the value type for maps.
   108  	// For arrays (always a fixed size), Range holds
   109  	// the element type.  Otherwise Range is
   110  	// typically null.
   111  	Range *Ztype `msg:",omitempty"`
   112  }
   113  
   114  // Schema is the top level container in Greenpack.
   115  // It all starts here.
   116  type Schema struct {
   117  
   118  	// SourcePath gives the path to the original Go
   119  	// source file that was parsed to produce this
   120  	// compiled schema.
   121  	SourcePath string
   122  
   123  	// SourcePackage notes the original package presented
   124  	// by the SourcePath file.
   125  	SourcePackage string
   126  
   127  	// GreenSchemaId is a randomly chosen but stable
   128  	// 53-bit positive integer identifier (see
   129  	// greenpack -genid) that can be used to distinguish schemas.
   130  	GreenSchemaId int64
   131  
   132  	// Structs holds the collection of the main data
   133  	// descriptor, the Struct. The key is identical
   134  	// to Struct.StructName.
   135  	//
   136  	// This a map rather than a slice in order to:
   137  	// a) insure there are no duplicate struct names; and
   138  	// b) make decoding easy and fast.
   139  	Structs map[string]*Struct
   140  
   141  	// Imports archives the imports in the SourcePath
   142  	// to make it possible to understand other package
   143  	// type references.
   144  	Imports []string
   145  }
   146  
   147  // Struct represents a single message or struct.
   148  type Struct struct {
   149  	// StructName is the typename of the struct in Go.
   150  	StructName string
   151  
   152  	// Fields hold the individual Field descriptors.
   153  	Fields []Field
   154  }
   155  
   156  // Field represents fields within a struct.
   157  type Field struct {
   158  
   159  	// Zid is the greenpack id.
   160  	//
   161  	// Zid numbering detects update collisions
   162  	// when two developers simultaneously add two
   163  	// new fields. Zid numbering allows sane
   164  	// forward/backward data evolution, like protobufs
   165  	// and Cap'nProto.
   166  	//
   167  	// Zid follows Cap'nProto numbering semantics:
   168  	// start at numbering at 0, and strictly/always
   169  	// increase numbers monotically.
   170  	//
   171  	// No gaps and no duplicate Zid are allowed.
   172  	//
   173  	// Duplicate numbers are how collisions (between two
   174  	// developers adding two distinct new fields independently
   175  	// but at the same time) are detected.
   176  	//
   177  	// Therefore this ironclad rule: never delete a field or Zid number,
   178  	// just mark it as deprecated with the `deprecated:"true"`
   179  	// tag. Change its Go type to struct{} as soon as
   180  	// possible so that it becomes skipped; then the Go
   181  	// compiler can help you detect and prevent unwanted use.
   182  	//
   183  	Zid int64
   184  
   185  	// the name of the field in the Go schema/source file.
   186  	FieldGoName string
   187  
   188  	// optional wire-name designated by a
   189  	// `msg:"tagname"` tag on the struct field.
   190  	FieldTagName string `msg:",omitempty"`
   191  
   192  	// =======================
   193  	// type info
   194  	// =======================
   195  
   196  	// human readable/Go type description
   197  	FieldTypeStr string `msg:",omitempty"`
   198  
   199  	// the broad category of this type. empty if Skip is true
   200  	FieldCategory Zkind `msg:",omitempty"`
   201  
   202  	// avail if FieldCategory == BaseElemCat
   203  	FieldPrimitive Zkind `msg:",omitempty"`
   204  
   205  	// the machine-parse-able type tree
   206  	FieldFullType *Ztype `msg:",omitempty"`
   207  
   208  	// =======================
   209  	// field tag details:
   210  	// =======================
   211  
   212  	// if OmitEmpty then we don't serialize
   213  	// the field if it has its zero-value.
   214  	OmitEmpty bool `msg:",omitempty"`
   215  
   216  	// Skip means either type struct{} or
   217  	// other unserializable type;
   218  	// or marked  as `msg:"-"`. In any case,
   219  	// if Skip is true: do not serialize
   220  	// this field when writing, and ignore it
   221  	// when reading.
   222  	Skip bool `msg:",omitempty"`
   223  
   224  	// Deprecated means tagged with `deprecated:"true"`,
   225  	// or `msg:",deprecated"`.
   226  	// Compilers/libraries should discourage and warn
   227  	// users away from writing to such fields, while
   228  	// not making it impossible to either read or write
   229  	// the field.
   230  	Deprecated bool `msg:",omitempty"`
   231  
   232  	// ShowZero means display the field even if
   233  	// it has the zero value. Showzero has no impact
   234  	// on what is transmitted on the wire. Zero
   235  	// valued fields are never transmitted.
   236  	ShowZero bool `msg:",omitempty"`
   237  }