proto.go raw

   1  // Copyright 2014 Google Inc. All Rights Reserved.
   2  //
   3  // Licensed under the Apache License, Version 2.0 (the "License");
   4  // you may not use this file except in compliance with the License.
   5  // You may obtain a copy of the License at
   6  //
   7  //     http://www.apache.org/licenses/LICENSE-2.0
   8  //
   9  // Unless required by applicable law or agreed to in writing, software
  10  // distributed under the License is distributed on an "AS IS" BASIS,
  11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12  // See the License for the specific language governing permissions and
  13  // limitations under the License.
  14  
  15  // This file is a simple protocol buffer encoder and decoder.
  16  // The format is described at
  17  // https://developers.google.com/protocol-buffers/docs/encoding
  18  //
  19  // A protocol message must implement the message interface:
  20  //   decoder() []decoder
  21  //   encode(*buffer)
  22  //
  23  // The decode method returns a slice indexed by field number that gives the
  24  // function to decode that field.
  25  // The encode method encodes its receiver into the given buffer.
  26  //
  27  // The two methods are simple enough to be implemented by hand rather than
  28  // by using a protocol compiler.
  29  //
  30  // See profile.go for examples of messages implementing this interface.
  31  //
  32  // There is no support for groups, message sets, or "has" bits.
  33  
  34  package profile
  35  
  36  import (
  37  	"errors"
  38  	"fmt"
  39  	"slices"
  40  )
  41  
  42  type buffer struct {
  43  	field    int // field tag
  44  	typ      int // proto wire type code for field
  45  	u64      uint64
  46  	data     []byte
  47  	tmp      [16]byte
  48  	tmpLines []Line // temporary storage used while decoding "repeated Line".
  49  }
  50  
  51  type decoder func(*buffer, message) error
  52  
  53  type message interface {
  54  	decoder() []decoder
  55  	encode(*buffer)
  56  }
  57  
  58  func marshal(m message) []byte {
  59  	var b buffer
  60  	m.encode(&b)
  61  	return b.data
  62  }
  63  
  64  func encodeVarint(b *buffer, x uint64) {
  65  	for x >= 128 {
  66  		b.data = append(b.data, byte(x)|0x80)
  67  		x >>= 7
  68  	}
  69  	b.data = append(b.data, byte(x))
  70  }
  71  
  72  func encodeLength(b *buffer, tag int, len int) {
  73  	encodeVarint(b, uint64(tag)<<3|2)
  74  	encodeVarint(b, uint64(len))
  75  }
  76  
  77  func encodeUint64(b *buffer, tag int, x uint64) {
  78  	// append varint to b.data
  79  	encodeVarint(b, uint64(tag)<<3)
  80  	encodeVarint(b, x)
  81  }
  82  
  83  func encodeUint64s(b *buffer, tag int, x []uint64) {
  84  	if len(x) > 2 {
  85  		// Use packed encoding
  86  		n1 := len(b.data)
  87  		for _, u := range x {
  88  			encodeVarint(b, u)
  89  		}
  90  		n2 := len(b.data)
  91  		encodeLength(b, tag, n2-n1)
  92  		n3 := len(b.data)
  93  		copy(b.tmp[:], b.data[n2:n3])
  94  		copy(b.data[n1+(n3-n2):], b.data[n1:n2])
  95  		copy(b.data[n1:], b.tmp[:n3-n2])
  96  		return
  97  	}
  98  	for _, u := range x {
  99  		encodeUint64(b, tag, u)
 100  	}
 101  }
 102  
 103  func encodeUint64Opt(b *buffer, tag int, x uint64) {
 104  	if x == 0 {
 105  		return
 106  	}
 107  	encodeUint64(b, tag, x)
 108  }
 109  
 110  func encodeInt64(b *buffer, tag int, x int64) {
 111  	u := uint64(x)
 112  	encodeUint64(b, tag, u)
 113  }
 114  
 115  func encodeInt64s(b *buffer, tag int, x []int64) {
 116  	if len(x) > 2 {
 117  		// Use packed encoding
 118  		n1 := len(b.data)
 119  		for _, u := range x {
 120  			encodeVarint(b, uint64(u))
 121  		}
 122  		n2 := len(b.data)
 123  		encodeLength(b, tag, n2-n1)
 124  		n3 := len(b.data)
 125  		copy(b.tmp[:], b.data[n2:n3])
 126  		copy(b.data[n1+(n3-n2):], b.data[n1:n2])
 127  		copy(b.data[n1:], b.tmp[:n3-n2])
 128  		return
 129  	}
 130  	for _, u := range x {
 131  		encodeInt64(b, tag, u)
 132  	}
 133  }
 134  
 135  func encodeInt64Opt(b *buffer, tag int, x int64) {
 136  	if x == 0 {
 137  		return
 138  	}
 139  	encodeInt64(b, tag, x)
 140  }
 141  
 142  func encodeString(b *buffer, tag int, x string) {
 143  	encodeLength(b, tag, len(x))
 144  	b.data = append(b.data, x...)
 145  }
 146  
 147  func encodeStrings(b *buffer, tag int, x []string) {
 148  	for _, s := range x {
 149  		encodeString(b, tag, s)
 150  	}
 151  }
 152  
 153  func encodeBool(b *buffer, tag int, x bool) {
 154  	if x {
 155  		encodeUint64(b, tag, 1)
 156  	} else {
 157  		encodeUint64(b, tag, 0)
 158  	}
 159  }
 160  
 161  func encodeBoolOpt(b *buffer, tag int, x bool) {
 162  	if x {
 163  		encodeBool(b, tag, x)
 164  	}
 165  }
 166  
 167  func encodeMessage(b *buffer, tag int, m message) {
 168  	n1 := len(b.data)
 169  	m.encode(b)
 170  	n2 := len(b.data)
 171  	encodeLength(b, tag, n2-n1)
 172  	n3 := len(b.data)
 173  	copy(b.tmp[:], b.data[n2:n3])
 174  	copy(b.data[n1+(n3-n2):], b.data[n1:n2])
 175  	copy(b.data[n1:], b.tmp[:n3-n2])
 176  }
 177  
 178  func unmarshal(data []byte, m message) (err error) {
 179  	b := buffer{data: data, typ: 2}
 180  	return decodeMessage(&b, m)
 181  }
 182  
 183  func le64(p []byte) uint64 {
 184  	return uint64(p[0]) | uint64(p[1])<<8 | uint64(p[2])<<16 | uint64(p[3])<<24 | uint64(p[4])<<32 | uint64(p[5])<<40 | uint64(p[6])<<48 | uint64(p[7])<<56
 185  }
 186  
 187  func le32(p []byte) uint32 {
 188  	return uint32(p[0]) | uint32(p[1])<<8 | uint32(p[2])<<16 | uint32(p[3])<<24
 189  }
 190  
 191  func peekNumVarints(data []byte) (numVarints int) {
 192  	for ; len(data) > 0; numVarints++ {
 193  		var err error
 194  		if _, data, err = decodeVarint(data); err != nil {
 195  			break
 196  		}
 197  	}
 198  	return numVarints
 199  }
 200  
 201  func decodeVarint(data []byte) (uint64, []byte, error) {
 202  	var u uint64
 203  	for i := 0; ; i++ {
 204  		if i >= 10 || i >= len(data) {
 205  			return 0, nil, errors.New("bad varint")
 206  		}
 207  		u |= uint64(data[i]&0x7F) << uint(7*i)
 208  		if data[i]&0x80 == 0 {
 209  			return u, data[i+1:], nil
 210  		}
 211  	}
 212  }
 213  
 214  func decodeField(b *buffer, data []byte) ([]byte, error) {
 215  	x, data, err := decodeVarint(data)
 216  	if err != nil {
 217  		return nil, err
 218  	}
 219  	b.field = int(x >> 3)
 220  	b.typ = int(x & 7)
 221  	b.data = nil
 222  	b.u64 = 0
 223  	switch b.typ {
 224  	case 0:
 225  		b.u64, data, err = decodeVarint(data)
 226  		if err != nil {
 227  			return nil, err
 228  		}
 229  	case 1:
 230  		if len(data) < 8 {
 231  			return nil, errors.New("not enough data")
 232  		}
 233  		b.u64 = le64(data[:8])
 234  		data = data[8:]
 235  	case 2:
 236  		var n uint64
 237  		n, data, err = decodeVarint(data)
 238  		if err != nil {
 239  			return nil, err
 240  		}
 241  		if n > uint64(len(data)) {
 242  			return nil, errors.New("too much data")
 243  		}
 244  		b.data = data[:n]
 245  		data = data[n:]
 246  	case 5:
 247  		if len(data) < 4 {
 248  			return nil, errors.New("not enough data")
 249  		}
 250  		b.u64 = uint64(le32(data[:4]))
 251  		data = data[4:]
 252  	default:
 253  		return nil, fmt.Errorf("unknown wire type: %d", b.typ)
 254  	}
 255  
 256  	return data, nil
 257  }
 258  
 259  func checkType(b *buffer, typ int) error {
 260  	if b.typ != typ {
 261  		return errors.New("type mismatch")
 262  	}
 263  	return nil
 264  }
 265  
 266  func decodeMessage(b *buffer, m message) error {
 267  	if err := checkType(b, 2); err != nil {
 268  		return err
 269  	}
 270  	dec := m.decoder()
 271  	data := b.data
 272  	for len(data) > 0 {
 273  		// pull varint field# + type
 274  		var err error
 275  		data, err = decodeField(b, data)
 276  		if err != nil {
 277  			return err
 278  		}
 279  		if b.field >= len(dec) || dec[b.field] == nil {
 280  			continue
 281  		}
 282  		if err := dec[b.field](b, m); err != nil {
 283  			return err
 284  		}
 285  	}
 286  	return nil
 287  }
 288  
 289  func decodeInt64(b *buffer, x *int64) error {
 290  	if err := checkType(b, 0); err != nil {
 291  		return err
 292  	}
 293  	*x = int64(b.u64)
 294  	return nil
 295  }
 296  
 297  func decodeInt64s(b *buffer, x *[]int64) error {
 298  	if b.typ == 2 {
 299  		// Packed encoding
 300  		dataLen := peekNumVarints(b.data)
 301  		*x = slices.Grow(*x, dataLen)
 302  
 303  		data := b.data
 304  		for len(data) > 0 {
 305  			var u uint64
 306  			var err error
 307  
 308  			if u, data, err = decodeVarint(data); err != nil {
 309  				return err
 310  			}
 311  			*x = append(*x, int64(u))
 312  		}
 313  		return nil
 314  	}
 315  	var i int64
 316  	if err := decodeInt64(b, &i); err != nil {
 317  		return err
 318  	}
 319  	*x = append(*x, i)
 320  	return nil
 321  }
 322  
 323  func decodeUint64(b *buffer, x *uint64) error {
 324  	if err := checkType(b, 0); err != nil {
 325  		return err
 326  	}
 327  	*x = b.u64
 328  	return nil
 329  }
 330  
 331  func decodeUint64s(b *buffer, x *[]uint64) error {
 332  	if b.typ == 2 {
 333  		// Packed encoding
 334  		dataLen := peekNumVarints(b.data)
 335  		*x = slices.Grow(*x, dataLen)
 336  
 337  		data := b.data
 338  		for len(data) > 0 {
 339  			var u uint64
 340  			var err error
 341  
 342  			if u, data, err = decodeVarint(data); err != nil {
 343  				return err
 344  			}
 345  			*x = append(*x, u)
 346  		}
 347  		return nil
 348  	}
 349  	var u uint64
 350  	if err := decodeUint64(b, &u); err != nil {
 351  		return err
 352  	}
 353  	*x = append(*x, u)
 354  	return nil
 355  }
 356  
 357  func decodeString(b *buffer, x *string) error {
 358  	if err := checkType(b, 2); err != nil {
 359  		return err
 360  	}
 361  	*x = string(b.data)
 362  	return nil
 363  }
 364  
 365  func decodeStrings(b *buffer, x *[]string) error {
 366  	var s string
 367  	if err := decodeString(b, &s); err != nil {
 368  		return err
 369  	}
 370  	*x = append(*x, s)
 371  	return nil
 372  }
 373  
 374  func decodeBool(b *buffer, x *bool) error {
 375  	if err := checkType(b, 0); err != nil {
 376  		return err
 377  	}
 378  	if int64(b.u64) == 0 {
 379  		*x = false
 380  	} else {
 381  		*x = true
 382  	}
 383  	return nil
 384  }
 385