kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/go/util/keys/keys.go (about)

     1  /*
     2   * Copyright 2018 The Kythe Authors. All rights reserved.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *   http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  // Package keys implements orderedcode encodings for Kythe types.
    18  package keys // import "kythe.io/kythe/go/util/keys"
    19  
    20  import (
    21  	"fmt"
    22  
    23  	"github.com/google/orderedcode"
    24  
    25  	spb "kythe.io/kythe/proto/storage_go_proto"
    26  )
    27  
    28  // Append appends the encoded representations of items to the key buffer.
    29  //
    30  // In addition to the types supported by the orderedcode library, the following
    31  // Kythe types can be handled:
    32  //
    33  //   - *spb.VName
    34  //   - int32/int
    35  //   - bool
    36  //
    37  // More detail at: https://godoc.org/github.com/google/orderedcode#Append
    38  func Append(key []byte, items ...any) ([]byte, error) {
    39  	expanded := make([]any, 0, len(items))
    40  	for _, item := range items {
    41  		switch x := item.(type) {
    42  		case *spb.VName:
    43  			// Split into strings based on http://kythe.io/docs/kythe-storage.html ordering
    44  			if x == nil {
    45  				return nil, fmt.Errorf("cannot append nil %T", x)
    46  			}
    47  			expanded = append(expanded, x.Corpus, x.Language, x.Path, x.Root, x.Signature)
    48  		case int32:
    49  			// Convert to orderedcode supported int64 type
    50  			expanded = append(expanded, int64(x))
    51  		case int:
    52  			// Convert to orderedcode supported int64 type
    53  			expanded = append(expanded, int64(x))
    54  		case bool:
    55  			var n int64
    56  			if x {
    57  				n = 1
    58  			}
    59  			expanded = append(expanded, n)
    60  		default:
    61  			// Assume type is supported; let orderedcode produce error otherwise
    62  			expanded = append(expanded, x)
    63  		}
    64  	}
    65  	return orderedcode.Append(key, expanded...)
    66  }
    67  
    68  // Parse parses the next len(items) from the encoded key.
    69  //
    70  // In addition to the types supported by the orderedcode library, the following
    71  // Kythe types can be handled:
    72  //
    73  //   - *spb.VName
    74  //   - int32/int
    75  //   - bool
    76  //
    77  // More detail at: https://godoc.org/github.com/google/orderedcode#Parse
    78  func Parse(key string, items ...any) (remaining string, err error) {
    79  	// See Append implementation for details
    80  	expanded := make([]any, 0, len(items))
    81  	for _, item := range items {
    82  		switch x := item.(type) {
    83  		case *spb.VName:
    84  			expanded = append(expanded, &x.Corpus, &x.Language, &x.Path, &x.Root, &x.Signature)
    85  		case *int32:
    86  			var n int64
    87  			defer func() { *x = int32(n) }()
    88  			expanded = append(expanded, &n)
    89  		case *int:
    90  			var n int64
    91  			defer func() { *x = int(n) }()
    92  			expanded = append(expanded, &n)
    93  		case *bool:
    94  			var n int64
    95  			defer func() { *x = n != 0 }()
    96  			expanded = append(expanded, &n)
    97  		default:
    98  			expanded = append(expanded, x)
    99  		}
   100  	}
   101  	return orderedcode.Parse(key, expanded...)
   102  }