Referencing a enum defined in another proto - go

In A.proto, I defined an enum called Foo. Then in B.proto, I referenced this enum as:
message Bar {
.pathofA.Foo foo = 1;
}
Notice that A.proto does not have a go_proto_library declared. It's only in java. While B.proto has both go_proto_library and java_proto_library declared.
Now in C.go, I'm trying to build a Bar object, but I continuously got errors when trying to set the value for Foo. I could not import A.proto in C.go, as A does not have a go proto library. Would there be a way to reference/set value for Foo in C with only B.proto imported?
Many thanks for any help!

Related

Can you create struct tags in a separate file?

This is not a duplicate of How can I override json tags in a Go struct? - that asks an entirely different question!
Given this XML struct:
type Foo struct {
Bar string `xml:"bar"`
}
I'd like to define xml:"bar" in a config' file, elsewhere. Something like:
import (
"github.com/foo/app/config"
)
type Foo struct {
Bar string config.Bar
}
Where github.com/foo/app/config contains the following:
package config
const (
Bar = `xml:"bar"`
)
That doesn't work, though - any help to achieve something similar would be greatly appreciated.
Can you create struct tags in a separate config file?
No.
You even cannot change them during runtime.

Access enum name in Systemverilog

I want to be able to retrieve the names for the types in an enumeration without having to actually assign a variable to them. Hence, given an enumeration like this
class my_class;
typedef enum bit {
ONE,
TWO
} fsm_state_t;
endclass
I know I can access the name of a declared variable like this:
class another_class;
...
my_class::fsm_state_t state = my_class::ONE;
print(state.name());
...
endclass
Is it possible to access the names of the enum without actually having to declare and assign a variable? What I mean is something like this:
class another_class;
...
print(my_class::ONE);
print(my_class::TWO);
...
endclass
No, built-in methods cannot be called on types.
if someday the type is changed, the compiler notifies that the print
must be changed as well.
By simply "using" the enumeration within your code, if it goes away you'll get a compile error. That seems to be what you're duplicating. A more practical duplication would be to value check every enum:
class another_class;
...
if (my_class::ONE!=0) print("ONE has changed!");
if (my_class::TWO!=1) print("TWO has changed!");
...
endclass
EDIT: or create a wrapper class for enums
virtual class enum_wrap#(type T);
static function string name(T obj);
return obj.name();
endfunction
endclass
program testbench;
initial begin
typedef enum {ZERO, ONE, TWO, THREE} numbers_t;
$display("ENUM without variable: %s", enum_wrap#(numbers_t)::name(THREE));
end
endprogram
prints:
ENUM without variable: THREE

How to avoid import cycles in mock generation?

Simple example.
I have package xxx. This package contains:
struct A
interface B which is a field of A
struct C which is an argument in method of B
type A struct {
SomeField B
}
type B interface {
SomeMethod(c C)
}
Now imagine I want to create unit test for structure A and mock dependency B. For creating mock I am using mock generator. All mocks are stored in the common "mocks" folder.
The problem is that generated mock has a dependency on xxx package. This is happening because SomeMethod of interface B has argument xxx.C.
Whenever I try to import my mock structure in a_test.go it fails because of cycle import problem. xxx package importing mocks package in the a_test.go. and mocks package imports xxx package in my generated mock.
I need a peace of advice, what is the best workaround for this? Maybe my approach is not idiomatic enough. Where do you store your mocks?
You need to put your test under a different package.
a.go is under package xxx
a_test.go is under package xxx_test
a_mock.go is under package xxx_mock
This way a_test.go will be dependent on xxx and xxx_mock and will not cause dependency cycle.
Also, a.go and a_test.go can be under the same folder, like this:
xxx/
- a.go
- a_test.go
mock/
- a_mock.go
Since
interface
struct
user code
unit test for the user code
are all in the same package, the interface should be considered as "in-package" interface, which is invisible for code in other package. So, the mock for this interface should be IN THE SAME PACKAGE as the interface itself.
Conclusion:
interface
struct
user code
unit test for the user code
mock for the interface
PUT ALL OF THEM IN THE SAME PACKAGE.
So put the mock code generated by gomock into the same package as the interface, but not "mock" package. Example(windows version):
mockgen -source=.\foo\bar.go -destination=.\foo\bar_mock.go -package=foo
Compiling a_test.go as different package (ex. a_test) will resolve the cirucular import issue.
This is the io_test.go example from go language source. Associate question with example by replacing package xxx with package io and a_test with io_test.
//io_test.go
package io_test
import{
. "io" //wildcard import
}
// io_test code
However there wont be access to non-exported type in package io. To make the non-exported type to exported type we could add a file export_test.go and define a exported and assign non-exported type to exported type.
//export_test.go
package io
// exported for test
var IOExportedType= ioNonExportedType
Use a top level package that all other packages import from. Put your interfaces there.
For instance:
domain/
interfaces.go
a/
mock.go
b/
mock.go
c/
mock.go
a, b and c should import from domain so they don't have any dependencies on each other. You will use duck typing to implement the interfaces of the domain package in your mocks.
Here's an actual use case using your example:
domain/interfaces.go:
type A interface {
Foo()
}
type B interface {
Bar() string
}
type C interface {
Baz() string
}
a/mock.go:
type A struct {
SomeField domain.B
}
// ...
b/mock.go:
type B struct {
SomeMethod(c domain.C)
}
// ...
c/mock.go:
type C struct {}
// ...
That should compile just fine, because all the mocks import from the top level domain package, and they all implement the respective interfaces.
In case of avoiding self referencing in Go 1.17
Add this arg
-self_package github.com/xxx
So
mockgen -source=<srcName>.go \
-package <pkgName> \
-self_package github.com/<user>/<repo>/<pkgName> \
-destination <dest>.go

Code explanation of the json11 library about implicit constructor

I'm reading the source code of the main json11 header file.
It contains the following declaration:
template <class T, class = decltype(&T::to_json)>
Json(const T & t) : Json(t.to_json()) {}
I'm trying to find some documentation about this usage of decltype and class inside a template declaration but no success.
Does this construction/usage has a name in C++? Any good reference about it?
It's using SFINAE ("Substitution Failure Is Not An Error"), a common technique for advanced template stuff. In this case, it's used as a crude(1) test whether the type T has a function named to_json.
How it works: if the expression T::to_json is well-formed (there is something named to_json inside the type T), decltype(T::to_json) denotes a valid type and the constructor template can be used normally.
However, if T::to_json is ill-formed (i.e. if there is no to_json member inside T), it means substituting the template argument for T has failed. Per SFINAE, this is not an error of the entire program; it just means that the template is removed from further consideration (as if it was never part of the class).
The effect is thus that if type T has a member to_json, you can use an object of type T to initialise a Json object. If there is no such member in T, the constructor will not exist.
(1) I'm saying crude test because this only checks that T has such a member. It doesn't check that the member is a function which can be invoked without arguments and returns something another constructor of Json can accept. A tighter-fitting test might look something like this:
template <class T, class = std::enable_if_t<std::is_constructible<Json, decltype(std::declval<const T>().to_json())>::value>>
Json(const T & t) : Json(t.to_json()) {}
[Live example]

enum class in QVariant in QSettings

I have a problem with enum classes, QVariants and the QSettings class. There are enum class values that I want to store within a QVariant which goes into a QSettings instance. So, my code actually looks something like this:
enum class Foo
{
Bar1, Bar2
}
Q_ENUMS(Foo)
Q_DECLARE_METATYPE(Foo)
...
Foo value = Bar2;
QSettings settings;
settings.setValue(QString("Foo"), QVariant::fromValue(value));
At this point in executing the code, an assertion jumps in and complains:
ASSERT failure in QVariant::save: "Invalid type to save", file kernel\qvariant.cpp
Searching the internet, I found out that the class is missing a fitting << and >> operator. But that is not an option for enum classes. I even tried to use
qRegisterMetaType<Foo>("Foo");
but it did not help. Maybe you have some other suggestions/solutions for me. Thanks!
Enums, which are masked unsigned ints, seem to be a problem, see
Qt4 QSettings save enumeration value (for example Qt::CheckState)
The solution there and probably here would be to convert it an unsigned. To check if the static_cast-result back to the enum is valid you might add Foo_lowest and Foo_highest values to the beginning and end of the enum range.
You can use Q_ENUM since Qt 5.5 and not worry about calling qRegisterMetaType():
enum class Foo
{
Bar1, Bar2
}
Q_ENUM(Foo)
...
Foo value = Foo::Bar2;
QSettings settings;
settings.setValue(QString("Foo"), QVariant::fromValue(value));

Resources